简体   繁体   English

Python:创建元组列表的优雅方法?

[英]Python: elegant way of creating a list of tuples?

>>> a=["a"]*4
>>> a
['a', 'a', 'a', 'a']
>>> b=range(4)
>>> b
[0, 1, 2, 3]
>>> c = [range(4,8), range(9,13), range(14,18), range(19,23)]
>>> c
[[4, 5, 6, 7], [9, 10, 11, 12], [14, 15, 16, 17], [19, 20, 21, 22]]
>>>
>>> result = map(lambda x,y:[x,y],a,b)
>>> map(lambda x,y:x.extend(y),result,c)
>>> result = map(tuple, result)
>>> result     # desired output: 
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12), ('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]
>>>
>>> try_test = zip(a,b,c)
>>> try_test # NOT DESIRED: leaves me with the list within the tuples
[('a', 0, [4, 5, 6, 7]), ('a', 1, [9, 10, 11, 12]), ('a', 2, [14, 15, 16, 17]), ('a', 3, [19, 20, 21, 22])]

I was wondering whether anyone has a more succinct way to do the "result"? 我想知道是否有人有一个更简洁的方法来执行“结果”?

您可以尝试这样的事情:

result = [tuple([ai, bi] + ci) for ai, bi, ci in zip(a, b, c)]

For a fully general approach to this problem, you might consider using one of the many variations on flatten you can find here , where flatten is a function that takes an arbitrarily nested iterable of iterables and returns a flat list of the items contained therein. 对于此问题的完全通用方法,您可以考虑使用可在此处找到的flatten的多种变体之一,其中flatten是一个函数,该函数采用任意嵌套的iterable的iterable并返回其中包含的项的flat列表。

Then just map flatten over the zipped values of a, b, c and convert to tuple. 然后,只需映射flatten了的压缩值a, b, c ,并转换为元组。

>>> from collections import Iterable
>>> def flatten(l):
...     for i in l:
...         if isinstance(i, Iterable) and not isinstance(i, basestring):
...             for sub in flatten(i):
...                 yield sub
...         else:
...             yield i
...
>>> map(tuple, map(flatten, zip(a, b, c)))
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12), 
 ('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]

Or even more succinctly, modify flatten to accept an arbitrary argument list and return a tuple. 或更简洁地说,修改flatten以接受任意参数列表并返回一个元组。 Then all you need is map : 然后,您需要的就是map

>>> def flat_tuple(*args):
...     return tuple(flatten(args))
... 
>>> map(flat_tuple, a, b, c)
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12), 
 ('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]

If this is a one-off problem, the above approach is probably more trouble than it's worth. 如果这是一个一次性的问题,那么上述方法可能会带来更大的麻烦。 But if you've already defined flatten for other purposes, or if you're doing this frequently, the above could save you a lot of trouble! 但是,如果您已经为其他目的定义了flatten ,或者您经常这样做,则上述操作可以省去很多麻烦!

Otherwise, just for the fun of it, here's a variation on nneonneo 's answer that I like: 否则,仅出于乐趣,这是我喜欢nneonneo的答案的一个变体:

>>> [x + tuple(y) for x, y in zip(zip(a, b), c)]
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12), 
 ('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]

For this very case: (if succinct == short) 在这种情况下:(如果简短==短)

q = lambda x : tuple(range(x,x+4))
res = [ ('a', num) + q(4*(num+1)+num) for num in xrange(4) ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM