【问题标题】:How could i refresh a list once an item has been removed from a list within a list in python一旦从python列表中的列表中删除了一个项目,我如何刷新列表
【发布时间】:2012-03-20 21:11:33
【问题描述】:

这很复杂,但我希望能够在项目从较大列表中的迷你列表中取出后刷新较大的列表。

listA = ['1','2','3','4','5','6','6','8','9','5','3','7']

我使用下面的代码将其拆分为三个列表

split = [listA[i:(i+3)] for i in range(0, len(listA) - 1, 3)]

print(split)

# [['1','2','3'],['4','5','6'],['6','8','9'],['5','3','7']]

split = [['1','2','3'],['4','5','6'],['6','8','9'],['5','3','7']]

如果我从第一个列表中删除#3,现在将拆分

del split[0][-1]
split = [['1','2'],['4','5','6'],['6','8','9'],['5','3','7']]

#3 被删除后,我希望能够刷新列表,使其看起来像;

split = [['1','2','4'],['5','6','6'],['8','9','5'],['3','7']]

提前致谢

【问题讨论】:

  • 所以你不会每次都重新计算?
  • 你能告诉我们你为什么需要它的背景吗?
  • @RikPoggi:我需要这个来在纸牌游戏中翻牌。此外,移除当前显示的卡片。但是,我的游戏是在 python shell 中玩的。
  • @CodeBisector:你不应该那样做,一次生成 3 张卡片的生成器会好得多。
  • @RikPoggi:那会是哪个生成器?

标签: python list split


【解决方案1】:

不确定这个列表有多大,但您需要将其展平并重新计算:

>>> listA = ['1','2','3','4','5','6','6','8','9','5','3','7']
>>> split = [listA[i:(i+3)] for i in range(0, len(listA) - 1, 3)]
>>> split
[['1', '2', '3'], ['4', '5', '6'], ['6', '8', '9'], ['5', '3', '7']]
>>> del split[0][-1]
>>> split
[['1', '2'], ['4', '5', '6'], ['6', '8', '9'], ['5', '3', '7']]
>>> listA = sum(split, []) # <- flatten split list back to 1 level
>>> listA
['1', '2', '4', '5', '6', '6', '8', '9', '5', '3', '7']
>>> split = [listA[i:(i+3)] for i in range(0, len(listA) - 1, 3)]
>>> split
[['1', '2', '4'], ['5', '6', '6'], ['8', '9', '5'], ['3', '7']]

【讨论】:

    【解决方案2】:

    只需从嵌套列表中重新创建单个列表,然后重新拆分。

    您可以加入列表,假设它们只有一层,例如:

    rejoined = [element for sublist in split for element in sublist]
    

    毫无疑问,有更好的方法,或者使用 itertools 或其他一些库的单行程序,但不要想太多。如果您只谈论几百甚至几千个项目,这个解决方案已经足够了。

    【讨论】:

    • 更简单的加入方式是sum(foo, [])
    • @FakeRainBrigand:是的,尽管我认为这会产生误导性代码,因为您实际上并没有总结一些东西。 OTOH,乍一看很难理解像我展示的那样的列表理解。可能最明显的方法是使用itertools.chain,但是当您可以使用内置函数完成工作时,我不喜欢为一行代码引入整个模块。感谢您的评论。
    【解决方案3】:

    我需要这个来在纸牌游戏中翻牌。

    你可以用itertools.groupby()发牌,按键功能很好:

    def group_key(x, n=3, flag=[0], counter=itertools.count(0)):
        if next(counter) % n == 0:
            flag[0] = flag[0] ^ 1
        return flag[0]
    

    ^ 是一个bitwise operator,基本上它将标志的值从0 更改为1,反之亦然。标志值是列表的一个元素,因为我们正在做某种记忆。

    例子:

    >>> deck = ['1', '2', '3', '4', '5', '6', '6', '8', '9', '5', '3', '7']
    >>> for k,g in itertools.groupby(deck, key=group_key):
    ...     print(list(g))
    ['1', '2', '3']
    ['4', '5', '6']
    ['6', '8', '9']
    ['5', '3', '7']
    

    现在假设您使用了卡片“9”和“8”,因此您的新套牌如下所示:

    >>> deck = ['1', '2', '3', '4', '5', '6', '6', '5', '3', '7']
    >>> for k,g in itertools.groupby(deck, key=group_key):
    ...     print(list(g))
    ['1', '2', '3']
    ['4', '5', '6']
    ['6', '5', '3']
    ['7']
    

    【讨论】:

    • 你怎么能把它放在一个函数中。
    • @CodeBisector:只需将 for 循环放入一个接受 deck 作为参数并接受 yield list(g) 而不是 print 的函数中,然后像生成器(迭代器)一样使用它。否则将其设为return [list(g) for k,g in itertools.groupby(deck, key=group_key)]。选择权在你。
    • @CodeBisector:我真的不知道你的游戏是什么样的,所以请随意忽略我要告诉你的内容,但我想说你可能想把这段代码在一些Deck 类的deal 方法内。
    【解决方案4】:

    构建一个包含列表的对象,并在列表更改时跟踪(可能通过控制对其的写入),然后让对象在每次数据更改时进行自己的拆分,并将拆分列表保存到对象。

    【讨论】:

      猜你喜欢
      • 2014-05-25
      • 1970-01-01
      • 2022-12-20
      • 2017-08-02
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多