将整数列表转换为一个数字?

我有一个整数列表,我想转换为一个数字,如:

numList = [1, 2, 3] num = magic(numList) print num, type(num) >>> 123, <type 'int'> 

实现魔术function的最好方法是什么?

编辑
我确实发现了这一点 ,但好像还有更好的办法。

 # 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) 

两种解决scheme

 >>> 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导向的解决scheme实际上是在我的盒子上出现的 – 你绝对不应该使用sum可能是大数的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(numbers): return int(''.join([ "%d"%x for x in numbers])) 
 def magic(number): return int(''.join(str(i) for i in number)) 

为了完整起见,下面是一个使用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) 

不同解决scheme的时间performance

我测量了@ cdleary函数的性能。 结果稍有不同。

每个functiontesting与input列表生成的:

 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) num len(nums)1..30

     def _accumulator(nums): tot = 0 for num in nums: tot *= 10 tot += num return tot 
  • len(nums) num len(nums)30..1000

     def _map(nums): return int(''.join(map(str, nums))) def _imap(nums): return int(''.join(imap(str, nums))) 

图:N = 1000

 |------------------------------+-------------------| | 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 | 

图:N = 1000_000

要绘制第一个图下载cdleary.pymake-figures.py并运行( numpymatplotlib必须安装到绘图):

 $ 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

   while(!nums.isEmpty())
   {
     int digit = nums.takeFirst()
     tot * = 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 

使用生成器expression式:

 def magic(numbers): digits = ''.join(str(n) for n in numbers) return int(digits) 

如果列表只包含整数:

 reduce(lambda x,y: x*10+y, list) 

一个单线不需要投入和退出

 def magic(num): return sum(e * 10**i for i, e in enumerate(num[::-1])) 

我发现一些例子不兼容python 3我testing@Triptych一个

s = filter(str.isdigit, repr(numList)) num = int(s)

在python3它会给错误

TypeError: int() argument must be a string, a bytes-like object or a number, not 'filter'

我认为更简单和兼容的方式将是

 def magic(num_list): return int("".join(map(str, num_list))) 

这可能会有所帮助

 def digits_to_number(digits): return reduce(lambda x,y : x+y, map(str,digits)) print digits_to_number([1,2,3,4,5])