是否有规范的方法从输入序列中的单个项目发出多个键,以便它们形成连续的序列,我不需要使用reduce(...)
来平整序列?
e.g。如果我想将一系列数字中的每个数字扩展为一个序列中的单个数字
[1,12,123,1234,12345] => [1,1,2,1,2,3,1,2,3,4,1,2,3,4,5]
然后我会写一些看起来有点像这样的python:
somedata = [1,12,123,1234,12345]
listified = map(lambda x:[int(c) for c in str(x)], somedata)
flattened = reduce(lambda x,y: x+y,listified,[])
但如果有更简洁(或更有效)的表达方式,我宁愿不要调用flattened = reduce(...)
。
答案 0 :(得分:3)
map(func, *iterables)
将始终将func
调用为最短迭代次数的长度(假设没有引发异常)。函数始终返回单个对象。因此list(map(func, *iterables))
将始终具有与最短迭代相同的长度。
因此list(map(lambda x:[int(c) for c in str(x)], somedata))
的长度始终与somedata
相同。没有办法解决这个问题。
如果所需结果(例如[1,1,2,1,2,3,1,2,3,4,1,2,3,4,5]
)的项目多于输入(例如[1,12,123,1234,12345]
),则必须使用map
以外的其他内容来生成它。
例如,您可以使用itertools.chain.from_iterable
来展平2个嵌套级别:
In [31]: import itertools as IT
In [32]: somedata = [1,12,123,1234,12345]
In [33]: list(map(int, IT.chain.from_iterable(map(str, somedata))))
Out[33]: [1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]
或者,为了展平列表列表,sum(..., [])
就足够了:
In [44]: sum(map(lambda x:[int(c) for c in str(x)], somedata), [])
Out[44]: [1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]
但请注意,这比使用IT.chain.from_iterable
要慢得多(见下文)。
这是一个基准(使用IPython' s %timeit
)测试10,000个整数列表中的各种方法,从0到100万:
In [4]: import random
In [8]: import functools
In [49]: somedata = [random.randint(0, 10**6) for i in range(10**4)]
In [50]: %timeit list(map(int, IT.chain.from_iterable(map(str, somedata))))
100 loops, best of 3: 9.35 ms per loop
In [13]: %timeit [int(i) for i in list(''.join(str(somedata)[1:-1].replace(', ','')))]
100 loops, best of 3: 12.2 ms per loop
In [52]: %timeit [int(j) for i in somedata for j in str(i)]
100 loops, best of 3: 12.3 ms per loop
In [51]: %timeit sum(map(lambda x:[int(c) for c in str(x)], somedata), [])
1 loop, best of 3: 869 ms per loop
In [9]: %timeit listified = map(lambda x:[int(c) for c in str(x)], somedata); functools.reduce(lambda x,y: x+y,listified,[])
1 loop, best of 3: 871 ms per loop
答案 1 :(得分:2)
有两个想法,一个有列表综合:
print [int(j) for i in somedata for j in str(i) ]
新的东西(来自评论),字符串已经可迭代,所以它将是:
print [int(i) for i in list(''.join(str(somedata)[1:-1].replace(', ','')))]
第二次对字符串和列表综合进行操作:
[1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]
两者的输出:
0k