【问题标题】:Using map and zip to determine if sequential items in list have a difference equal to 1使用 map 和 zip 确定列表中的连续项目是否有等于 1 的差
【发布时间】:2017-08-02 17:03:35
【问题描述】:

这里是 Python 初学者,寻求一些指导和见解。我有以下在 python 中工作的代码:

z=0
y=0
valid=[]
test = [1,2,1,3,4,4,5,2,6,7]

for i, j in zip(test, test[1:]):
    if (j - i) == 1:
        z += 1
    valid.append(i)
    valid.append(j)
else:
    y += 1

print("There are " + str(len(test)) + " entries with " + str(z) + " sequential events and " + str(y) + " non-sequentual events")

print(list(valid))

这给了我我希望的输出:

There are 10 entries with 4 sequential events and 5 non-sequentual events
[1, 2, 3, 4, 4, 5, 6, 7]

我更喜欢 Pythonic,我正在尝试使用 map 和 zip 重新创建它:

map(diff_val(help_here_pls), zip(test, test[1:]))

我知道地图遵循“地图(函数,可迭代)”。如何让我的地图输出与我的首选列表相匹配

[1, 2, 3, 4, 4, 5, 6, 7]

使用函数(help_here_pls")。

我知道:

  • zip 创建一个元组列表
  • map 采用函数和可迭代(在本例中来自我的 zip)

我是否通过 map 中的函数传递一个元组? lambda 可以处理这个,还是我需要定义一个单独的函数?即使我能做到这一点,我是否必须解包元组? (i ,j) = [通过的元组]

提前感谢您提供的任何指导!欢迎阅读/参考!

【问题讨论】:

  • 列表理解最好在这里:[n for tup in zip(test, test[1:]) for n in tup if tup[1]-tup[0] == 1]。虽然我更喜欢显示我有成对数字的结果,所以我会做 [(i,j) for (i,j) in zip(test, test[1:]) if j-i == 1][(1, 2), (3, 4), (4, 5), (6, 7)]
  • 当我运行你的例子时,我得到There are 10 entries with 4 sequential events and 1 non-sequentual events [1, 2, 2, 1, 1, 3, 3, 4, 4, 4, 4, 5, 5, 2, 2, 6, 6, 7]
  • @jacoblaw 我正在使用 python 3.4.3 在 C9.io 上运行。不知道那里发生了什么。

标签: python python-3.x dictionary lambda zip


【解决方案1】:

列表推导是这里的 Pythonic 选择。我将结果更改为给出一个元组列表,因为扁平列表掩盖了每对项目之间的关系。

test = [1,2,1,3,4,4,5,2,6,7]
valid = [(i,j) for (i,j) in zip(test, test[1:]) if j-i == 1]
s = "There are {} entries with {} sequential events and {} non-sequentual events"
print(s.format(len(test), len(valid), len(test)-1-len(valid)))
print(valid)

输出:

There are 10 entries with 4 sequential events and 5 non-sequentual events
[(1, 2), (3, 4), (4, 5), (6, 7)]

这是使用more_itertools的另一种方式:

from operator import sub # function for subtraction
from more_itertools import flatten, pairwise

list(flatten(t for t in pairwise(test) if sub(*t)==-1))

给予

[1, 2, 3, 4, 4, 5, 6, 7]

【讨论】:

  • 谢谢@steven!列表推导是处理这个问题的一种优雅方式。也许这是我描述事物的非 Pythonic 方式,但扁平列表实际上是我需要进一步处理的结果。我仍在尝试使用具有多个索引/迭代器的 for 循环。使用 valid = [n for tup in zip(test, test[1:]) for n in tup if tup[1]-tup[0] == 1]] 成功了
  • 再看这个,我在想有一种方法可以类似地解析整数列表,而无需最初的zip(a,a[1:]) 我会回来...
  • 我不喜欢扁平化列表的一点是,看[1, 2, 3, 4, 4, 5, 6, 7] 很难分辨出 1 和 2 相关,而 2 和 3 不相关。如果您确实使用扁平列表,那么您的连续事件数为len(valid)/2)
  • Ahhh... 那条打印线是我的“我如何调试/验证这个想法”。此解析最终将用于确定 datetime 对象的顺序性(这是一个词吗?)并抛出不连续的对象。我想如果我可以先用整数来计算,我可以在其他地方应用逻辑。
  • @lucholland:我添加了一个使用more_itertools 模块中的pairwiseflatten 的示例,它可以帮助您摆脱zip 并摆脱嵌套的for 循环。 (more_itertools 是您需要安装的外部模块。)
猜你喜欢
  • 2016-12-07
  • 1970-01-01
  • 2013-01-21
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 2022-07-30
相关资源
最近更新 更多