"0-2,4,8" 等等。 我仍在学习更多处理列表的 Py-6ren">
gpt4 book ai didi

list - 将整数列表转换为逗号分隔范围字符串的 Pythonic 方法

转载 作者:太空狗 更新时间:2023-10-29 16:53:48 24 4
gpt4 key购买 nike

我有一个整数列表,我需要将其解析为一系列范围。

例如:

 [0, 1, 2, 3] -> "0-3"
[0, 1, 2, 4, 8] -> "0-2,4,8"

等等。

我仍在学习更多处理列表的 Pythonic 方法,这对我来说有点困难。我最近的想法是创建一个列表列表来跟踪配对数字:

[ [0, 3], [4, 4], [5, 9], [20, 20] ]

然后我可以遍历这个结构,将每个子列表打印为一个范围或单个值。

我不喜欢在两次迭代中执行此操作,但我似乎无法跟踪每次迭代中的每个数字。我的想法是做这样的事情:

这是我最近的尝试。它有效,但我并不完全满意;我一直在想有一个更优雅的解决方案完全让我无法理解。字符串处理迭代不是最好的,我知道——这对我来说还很早:)

def createRangeString(zones):
rangeIdx = 0
ranges = [[zones[0], zones[0]]]
for zone in list(zones):
if ranges[rangeIdx][1] in (zone, zone-1):
ranges[rangeIdx][1] = zone
else:
ranges.append([zone, zone])
rangeIdx += 1

rangeStr = ""
for range in ranges:
if range[0] != range[1]:
rangeStr = "%s,%d-%d" % (rangeStr, range[0], range[1])
else:
rangeStr = "%s,%d" % (rangeStr, range[0])

return rangeStr[1:]

有没有一种直接的方法可以将其合并到一个迭代中?我还能做些什么来让它更像 Pythonic?

最佳答案

>>> from itertools import count, groupby
>>> L=[1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 19, 20, 22, 23, 40, 44]
>>> G=(list(x) for _,x in groupby(L, lambda x,c=count(): next(c)-x))
>>> print ",".join("-".join(map(str,(g[0],g[-1])[:len(g)])) for g in G)
1-4,6-9,12-13,19-20,22-23,40,44

这里的想法是将每个元素与 count() 配对。那么 value 和 count() 之间的差对于连续值是恒定的。 groupby() 完成剩下的工作

正如 Jeff 所建议的,count() 的替代方法是使用 enumerate()。这增加了一些需要在打印语句中删除的额外内容

G=(list(x) for _,x in groupby(enumerate(L), lambda (i,x):i-x))
print ",".join("-".join(map(str,(g[0][1],g[-1][1])[:len(g)])) for g in G)

更新:对于此处给出的示例列表,在我的计算机上使用 enumerate 的版本比使用 count() 的版本慢大约 5%

关于list - 将整数列表转换为逗号分隔范围字符串的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3429510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com