我有一个整数列表,我想转换为一个数字,如:
numList = [1, 2, 3] num = magic(numList) print num, type(num) >>> 123,
实现魔术功能的最佳方法是什么?
编辑
我确实找到了这个,但似乎必须有一个更好的方法.
# 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..30
def _accumulator(nums): tot = 0 for num in nums: tot *= 10 tot += num return tot
len(nums)
在30..1000
def _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 |
要绘制第一个图形下载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