정수 목록을 하나의 숫자로 변환 하시겠습니까?
다음과 같이 하나의 숫자로 변환하고 싶은 정수 목록이 있습니다.
numList = [1, 2, 3]
num = magic(numList)
print num, type(num)
>>> 123, <type 'int'>
매직 기능 을 구현하는 가장 좋은 방법은 무엇입니까 ?
편집
나는 이것을 찾았 지만 더 나은 방법이 있어야하는 것 같습니다.
# Over-explaining a bit:
def magic(numList): # [1,2,3]
s = map(str, numList) # ['1','2','3']
s = ''.join(s) # '123'
s = int(s) # 123
return s
# How I'd probably write it:
def magic(numList):
s = ''.join(map(str, numList))
return int(s)
# As a one-liner
num = int(''.join(map(str,numList)))
# Functionally:
s = reduce(lambda x,y: x+str(y), numList, '')
num = int(s)
# Using some oft-forgotten built-ins:
s = filter(str.isdigit, repr(numList))
num = int(s)
두 가지 솔루션 :
>>> nums = [1, 2, 3]
>>> magic = lambda nums: int(''.join(str(i) for i in nums)) # Generator exp.
>>> magic(nums)
123
>>> magic = lambda nums: sum(digit * 10 ** (len(nums) - 1 - i) # Summation
... for i, digit in enumerate(nums))
>>> magic(nums)
123
map
지향 솔루션은 실제로 내 상자에 앞서 나오는 - 당신은 확실히 사용하지 말아야 sum
많은 수있을 것을 위해 :
import collections
import random
import timeit
import matplotlib.pyplot as pyplot
MICROSECONDS_PER_SECOND = 1E6
FUNS = []
def test_fun(fun):
FUNS.append(fun)
return fun
@test_fun
def with_map(nums):
return int(''.join(map(str, nums)))
@test_fun
def with_interpolation(nums):
return int(''.join('%d' % num for num in nums))
@test_fun
def with_genexp(nums):
return int(''.join(str(num) for num in nums))
@test_fun
def with_sum(nums):
return sum(digit * 10 ** (len(nums) - 1 - i)
for i, digit in enumerate(nums))
@test_fun
def with_reduce(nums):
return int(reduce(lambda x, y: x + str(y), nums, ''))
@test_fun
def with_builtins(nums):
return int(filter(str.isdigit, repr(nums)))
@test_fun
def with_accumulator(nums):
tot = 0
for num in nums:
tot *= 10
tot += num
return tot
def time_test(digit_count, test_count=10000):
"""
:return: Map from func name to (normalized) microseconds per pass.
"""
print 'Digit count:', digit_count
nums = [random.randrange(1, 10) for i in xrange(digit_count)]
stmt = 'to_int(%r)' % nums
result_by_method = {}
for fun in FUNS:
setup = 'from %s import %s as to_int' % (__name__, fun.func_name)
t = timeit.Timer(stmt, setup)
per_pass = t.timeit(number=test_count) / test_count
per_pass *= MICROSECONDS_PER_SECOND
print '%20s: %.2f usec/pass' % (fun.func_name, per_pass)
result_by_method[fun.func_name] = per_pass
return result_by_method
if __name__ == '__main__':
pass_times_by_method = collections.defaultdict(list)
assert_results = [fun([1, 2, 3]) for fun in FUNS]
assert all(result == 123 for result in assert_results)
digit_counts = range(1, 100, 2)
for digit_count in digit_counts:
for method, result in time_test(digit_count).iteritems():
pass_times_by_method[method].append(result)
for method, pass_times in pass_times_by_method.iteritems():
pyplot.plot(digit_counts, pass_times, label=method)
pyplot.legend(loc='upper left')
pyplot.xlabel('Number of Digits')
pyplot.ylabel('Microseconds')
pyplot.show()
def magic(number):
return int(''.join(str(i) for i in number))
def magic(numbers):
return int(''.join([ "%d"%x for x in numbers]))
완전성을 위해 다음을 사용하는 변형이 있습니다 print()
(Python 2.6-3.x에서 작동).
from __future__ import print_function
try: from cStringIO import StringIO
except ImportError:
from io import StringIO
def to_int(nums, _s = StringIO()):
print(*nums, sep='', end='', file=_s)
s = _s.getvalue()
_s.truncate(0)
return int(s)
다양한 솔루션의 시간 성능
@cdleary의 기능 성능을 측정했습니다 . 결과는 약간 다릅니다.
다음에서 생성 된 입력 목록으로 테스트 된 각 함수 :
def randrange1_10(digit_count): # same as @cdleary
return [random.randrange(1, 10) for i in xrange(digit_count)]
--sequence-creator=yourmodule.yourfunction
명령 줄 인수 를 통해 자체 함수를 제공 할 수 있습니다 (아래 참조).
목록 ( len(nums) == digit_count
) 에서 주어진 정수 수에 대해 가장 빠른 함수 는 다음과 같습니다.
len(nums)
에서 1..30def _accumulator(nums): tot = 0 for num in nums: tot *= 10 tot += num return tot
len(nums)
에서 30..1000def _map(nums): return int(''.join(map(str, nums))) def _imap(nums): return int(''.join(imap(str, nums)))
|------------------------------+-------------------|
| Fitting polynom | Function |
|------------------------------+-------------------|
| 1.00 log2(N) + 1.25e-015 | N |
| 2.00 log2(N) + 5.31e-018 | N*N |
| 1.19 log2(N) + 1.116 | N*log2(N) |
| 1.37 log2(N) + 2.232 | N*log2(N)*log2(N) |
|------------------------------+-------------------|
| 1.21 log2(N) + 0.063 | _interpolation |
| 1.24 log2(N) - 0.610 | _genexp |
| 1.25 log2(N) - 0.968 | _imap |
| 1.30 log2(N) - 1.917 | _map |
첫 번째 Figure를 다운로드 cdleary.py
하고make-figures.py
실행하려면 ( numpy
그리고 matplotlib
플롯하려면 설치해야 함) :
$ python cdleary.py
또는
$ python make-figures.py --sort-function=cdleary._map \
> --sort-function=cdleary._imap \
> --sort-function=cdleary._interpolation \
> --sort-function=cdleary._genexp --sort-function=cdleary._sum \
> --sort-function=cdleary._reduce --sort-function=cdleary._builtins \
> --sort-function=cdleary._accumulator \
> --sequence-creator=cdleary.randrange1_10 --maxn=1000
의사 코드 :
int magic (목록 번호) { int tot = 0 동안 (! nums.isEmpty ()) { 정수 숫자 = nums.takeFirst () 토트 * = 10 tot + = 자리 } 돌아온다 }
이것은 나에게 꽤 깨끗한 것 같습니다.
def magic( aList, base=10 ):
n= 0
for d in aList:
n = base*n + d
return n
이 방법은 목록의 각 요소가 단일 숫자 인 한 2.x에서 작동합니다. 그러나 실제로 이것을 사용해서는 안됩니다. 끔찍합니다.
>>> magic = lambda l:int(`l`[1::3])
>>> magic([3,1,3,3,7])
31337
생성기 표현식 사용 :
def magic(numbers):
digits = ''.join(str(n) for n in numbers)
return int(digits)
캐스트 할 필요가없는 원 라이너 str
def magic(num):
return sum(e * 10**i for i, e in enumerate(num[::-1]))
목록에 정수만 포함 된 경우 :
reduce(lambda x,y: x*10+y, list)
I found some examples are not compatible with python 3 I test one from @Triptych
s = filter(str.isdigit, repr(numList))
num = int(s)
in python 3 it's gonna give error
TypeError: int() argument must be a string, a bytes-like object or a number, not 'filter'
i think the more simple and compatible way would be
def magic(num_list):
return int("".join(map(str, num_list)))
This may be helpful
def digits_to_number(digits):
return reduce(lambda x,y : x+y, map(str,digits))
print digits_to_number([1,2,3,4,5])
If you happen to be using numpy (with import numpy as np
):
In [24]: x
Out[24]: array([1, 2, 3, 4, 5])
In [25]: np.dot(x, 10**np.arange(len(x)-1, -1, -1))
Out[25]: 12345
I found this thread while trying to convert a list to the real value of the underlying int in terms of a C-style pointer, but none of the other answers appear to work for this case. I think the following solution works as intended and could be useful to others even though it doesn't necessarily answer the original question.
def listToInt(x, reverseBytes=False):
if reverseBytes:
x = x[::-1]
return reduce(lambda x,y: x*256+y, x)
listToInt([1, 249]) == 505
listToInt([249, 1], True) == 505
The primary value of this is to emulate the behavior of casting a byte array to another data type, e.g. uint16, which Python can't seem to do natively, on either a big or little endian system.
참고 URL : https://stackoverflow.com/questions/489999/convert-list-of-ints-to-one-number
'IT박스' 카테고리의 다른 글
Mongoose 문서를 json으로 변환 (0) | 2020.11.29 |
---|---|
Protobuf가 공유 라이브러리를 찾을 수 없습니다. (0) | 2020.11.29 |
자바의 익명 코드 블록 (0) | 2020.11.29 |
아코디언을 열어 두도록 Twitter Bootstrap 축소 플러그인 수정 (0) | 2020.11.29 |
웹 사이트에서 C #으로 파일을 다운로드하는 방법 (0) | 2020.11.29 |