7

我正在为我的任务制作一个心脏游戏,但我不知道如何获取列表列表中的每个元素:

>>>Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C],["JH"]],[["7D"]]]

我想到的是:

for values in cards:
    for value in values:

但我想我刚刚得到了有 2 个列表的元素。如何计算卡片中有 3 和 1 的列表?

4

9 回答 9

15

像这样:

>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> from compiler.ast import flatten
>>> flatten(Cards) 
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']

正如 nacholibre 指出的那样,该compiler软件包已被弃用。这是的来源flatten

def flatten(seq):
    l = []
    for elt in seq:
        t = type(elt)
        if t is tuple or t is list:
            for elt2 in flatten(elt):
                l.append(elt2)
        else:
            l.append(elt)
    return l
于 2013-05-24T12:23:27.417 回答
6

略显晦涩的oneliner:

>>> [a for c in Cards for b in c for a in b]
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7', 'D']

您可能想要为 a、b 和 c 提供更具描述性的名称。

于 2013-05-24T12:16:03.337 回答
4

如果您的卡片以一种笨拙的方式嵌套:

>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> def getCards(cardList,myCards=[]): #change this to myCards, and pass in a list to mutate this is just for demo
        if isinstance(cardList,list):
            for subList in cardList:
                getCards(subList)
        else:
            myCards.append(cardList)
        return myCards
>>> getCards(Cards)
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']

将递归地遍历列表并找到所有元素。这些是我运行的一些时间,将所选flattern方法的性能与我的方法进行比较:

>>> print(timeit.timeit(r'getCards([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]],[])',setup="from clas import getCards"))
5.24880099297
>>> timeit.timeit(r'flatten([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]])',setup="from compiler.ast import flatten")
7.010887145996094
于 2013-05-24T12:13:25.463 回答
2

您的列表是一个不完整的嵌套列表,因此您可以先使其成为矩形,例如使用此处说明的过程,然后将结果展平numpy.ndarray

如果最后一个元素 ['7D'] 是 [['7D']] (那么其他答案也可以),则下面的“ifs”也不是必需的。

import numpy as np
collector = np.zeros((3,3,3),dtype='|S20')

for (i,j,k), v in np.ndenumerate( collector ):
    try:
        if not isinstance(cards[i], str):
            if not isinstance(cards[i][j], str):
                collector[i,j,k] = cards[i][j][k]
            else:
                collector[i,j,0] = cards[i][j]
        else:
            collector[i,0,0] = cards[i]
    except IndexError:
        collector[i,j,k] = ''

print collector[collector<>''].flatten()
于 2013-05-24T13:23:42.400 回答
2

使用生成器,可以编写更具可读性的实现flatten

def flatten(l):
    if isinstance(l, list):
        for e1 in l:
            for e2 in flatten(e1):
                yield e2
    else:
        yield l

或者,如果您使用的是 Python 3.3,它添加了以下yield from语法:

def flatten(l):
    if isinstance(l, list):
        for e in l:
            yield from flatten(e)
    else:
        yield l

结果:

>>> list(flatten([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],[["7D"]]]))
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
于 2013-05-24T14:08:37.423 回答
2

使用 2 个嵌套的itertools.chain来展平列表:

In [32]: Cards
Out[32]: [[['QS', '5H', 'AS'], ['2H', '8H'], ['7C']], [['9H', '5C'], ['JH']], ['7D']]

In [33]: from itertools import chain

In [34]: [k for k in chain.from_iterable([i for i in chain.from_iterable(Cards)])]
Out[34]: ['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7', 'D']
于 2013-05-24T14:10:14.590 回答
2

这个解决方案对于任何类型的嵌套列表或元组都非常健壮(要添加其他可迭代类型,只需or isinstance(...)在下面的代码中添加更多内容。

它只是递归地调用一个展开自身的函数:

def unfold(lst):
    output = []
    def _unfold(i):
        if isinstance(i, list) or isinstance(i, tuple):
            [_unfold(j) for j in i]
        else:
            output.append(i)
    _unfold(lst)
    return output

print unfold(cards)
#['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
于 2013-05-24T14:24:25.473 回答
1

使用来自 Rosetta Code的展平列表,您可以执行以下操作:

>>> def flatten(lst):
    return sum( ([x] if not isinstance(x, list) else flatten(x)
             for x in lst), [] )

>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> flatten(Cards)
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
>>> 

该解决方案仅展平嵌套列表 - 而不是元组或字符串。

于 2013-05-24T20:13:12.977 回答
1
from itertools import chain, imap

l= [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],[["7D"]]]

k = list(chain.from_iterable(imap(list, l)))
m = list(chain.from_iterable(imap(list, k)))

print m

输出:['QS','5H','AS','2H','8H','7C','9H','5C','JH','7D']

Itertools 太棒了!

于 2013-05-31T11:36:29.767 回答