【问题标题】:Reduce a list in a specific way以特定方式减少列表
【发布时间】:2018-08-01 14:27:41
【问题描述】:

我有一个字符串列表,如下所示:

['(num1, num2):1', '(num3, num4):1', '(num5, num6):1', '(num7, num8):1']

我试图实现的是减少这个列表并组合每两个元素,我想这样做直到只剩下一个大字符串元素。 所以中间列表看起来像这样:

['((num1, num2):1,(num3, num4):1)', '((num5, num6):1,(num7, num8):1)']

复杂的是(如您在中间列表中所见),两个字符串需要用括号括起来。所以对于上面提到的起点,最终的结果应该是这样的:

(((num_1,num_2):1,(num_3,num_4):1),((num_5,num_6):1,(num_7,num_8):1))

当然,这对于起始列表中的 8、16 或更多字符串元素也应该以通用方式工作。或者更准确地说,它应该适用于a<sub>n</sub>=2<sup>(n+1)</sup>

只需要非常具体地说明 8 个元素的结果应该如何:

'((((num_1,num_2):1,(num_3,num_4):1),((num_5,num_6):1,(num_7,num_8):1)),(((num_9,num_10):1,(num_11,num_12):1),((num_13,num_14):1,(num_15,num_16):1)))'

我已经使用嵌套的 for 循环解决了这个问题,但我认为应该有一个更实用或更快捷的解决方案。

我还在 stackoverflow 上找到了this solution

import itertools as it
l = [map( ",".join ,list(it.combinations(my_list, l))) for l in range(1,len(my_list)+1)]

虽然连接还不错,但我仍然需要括号。我尝试使用:

"{},{}".format

而不是.join,但这似乎很容易工作:)。

我也想过使用 reduce,但显然这不是正确的功能。也许可以实现自己的reduce函数左右?

我希望一些高级的pythonics可以帮助我。

【问题讨论】:

  • 您的中间列表中有一些额外的引号......
  • 另外,你能展示你的嵌套循环解决方案吗?
  • 另外,如果您的列表没有两个元素的幂会怎样?
  • 没有其他人认为这是一个非常奇怪的请求,一种存储数据的低效方式并且可能是一个 XY 问题?不?好的...(对于初学者来说,为什么初始列表不是有序字典?)
  • @MadPhysicist 对不起,额外的报价。我编辑了我的帖子。此外,我明天将添加嵌套的 for 循环代码(我很着急)。用例仅适用于定义数量的元素。由于我创建了一个类,如果输入的数字不正确,我会报错。

标签: python reduce


【解决方案1】:

听起来像是zip 集群习语的工作:zip(*[iter(x)]*n),您想将可迭代的x 分解为大小n 块。这将丢弃不构成完整块的“剩余”元素。对于x=[1, 2, 3]n=2,这将产生(1, 2)

def reducer(l):
    while len(l) > 1:
        l = ['({},{})'.format(x, y) for x, y in zip(*[iter(l)]*2)]
    return l

reducer(['(num1, num2):1', '(num3, num4):1', '(num5, num6):1', '(num7, num8):1'])
# ['(((num1, num2):1,(num3, num4):1),((num5, num6):1,(num7, num8):1))']

【讨论】:

  • 谢谢,这正是我需要的。这段代码很棒。只是为了理解代码,让我回顾一下正在发生的事情。我将在另一个答案中这样做。如果您能同意/不同意我的解释并更新它,如果它缺少细节,那就太好了。
【解决方案2】:

这是对zip(*[iter(l)]*2)中发生的事情的解释

[iter(l)*2] 这将创建一个长度为 2 的列表,其中包含两倍相同的可迭代元素,或者更准确地说,具有对同一个迭代对象的两个引用。

zip(*...) 进行提取。它拉动:

  1. 循环

    • iter-object 的第一个引用中的第一个元素
    • iter-object 的第二个引用中的第二个元素
  2. 循环

    • iter-object 的第一个引用中的第三个元素
    • iter 对象的第二个引用中的第四个元素
  3. 循环

    • iter-object 的第一个引用的第五个元素
    • iter-object 的第二个引用中的第六个元素

等等……

因此,我们在 for 循环中提供了提取的元素,并且可以将它们用作 xy 以进行进一步处理。

这真的很方便。

我也想指出this thread,因为它帮助我理解了这个概念。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-21
    • 2014-12-09
    • 2015-05-18
    • 2017-10-15
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多