Python“所有其他元素”成语

发布于 2024-08-28 22:06:29 字数 402 浏览 6 评论 0原文

我觉得我花了很多时间用 Python 编写代码,但没有足够的时间创建 Pythonic 代码。最近我遇到了一个有趣的小问题,我认为可能有一个简单、惯用的解决方案。解释一下原文,我需要收集列表中的每个连续对。例如,给定列表 [1,2,3,4,5,6],我想计算 [(1,2),(3,4),(5, 6)]

当时我想出了一个快速解决方案,看起来像是翻译后的 Java。重新审视这个问题,我能做的最好的事情就是

l = [1,2,3,4,5,6]
[(l[2*x],l[2*x+1]) for x in range(len(l)/2)]

在长度不均匀的情况下丢弃最后一个数字的副作用。

我是否缺少一种更惯用的方法,或者这是我能得到的最好的方法?

I feel like I spend a lot of time writing code in Python, but not enough time creating Pythonic code. Recently I ran into a funny little problem that I thought might have an easy, idiomatic solution. Paraphrasing the original, I needed to collect every sequential pair in a list. For example, given the list [1,2,3,4,5,6], I wanted to compute [(1,2),(3,4),(5,6)].

I came up with a quick solution at the time that looked like translated Java. Revisiting the question, the best I could do was

l = [1,2,3,4,5,6]
[(l[2*x],l[2*x+1]) for x in range(len(l)/2)]

which has the side effect of tossing out the last number in the case that the length isn't even.

Is there a more idiomatic approach that I'm missing, or is this the best I'm going to get?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

雨后咖啡店 2024-09-04 22:06:29

这会做得更整齐一些:(

>>> data = [1,2,3,4,5,6]
>>> zip(data[0::2], data[1::2])
[(1, 2), (3, 4), (5, 6)]

但如果您不熟悉范围的“跨步”功能,它的可读性可能会降低)。

与您的代码一样,它会丢弃具有奇数个值的最后一个值。

This will do it a bit more neatly:

>>> data = [1,2,3,4,5,6]
>>> zip(data[0::2], data[1::2])
[(1, 2), (3, 4), (5, 6)]

(but it's arguably less readable if you're not familiar with the "stride" feature of ranges).

Like your code, it discards the last value where you have an odd number of values.

去了角落 2024-09-04 22:06:29

经常被引用的一个是:

zip(*[iter(l)] * 2)

我更喜欢这个更具可读性的 iter 解决方案版本:

it = iter(l)
list(zip(it, it))
# [(1, 2), (3, 4), (5, 6)]

The one often-quoted is:

zip(*[iter(l)] * 2)

I prefer this more readable version of the iter solution:

it = iter(l)
list(zip(it, it))
# [(1, 2), (3, 4), (5, 6)]
吹泡泡o 2024-09-04 22:06:29

使用 range() 的步进功能怎么样:

[(l[n],l[n+1]) for n in range(0,len(l),2)]

How about using the step feature of range():

[(l[n],l[n+1]) for n in range(0,len(l),2)]
温柔戏命师 2024-09-04 22:06:29

我通常将 itertools 文档中的 grouper 配方复制到我的为此的代码。

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

I usually copy the grouper recipe from the itertools documentation into my code for this.

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)
画尸师 2024-09-04 22:06:29

试试这个

def pairs(l, n):
    return zip(*[l[i::n] for i in range(n)])

所以,

pairs([1, 2, 3, 4], 2)
给出

[(1, 2), (3, 4)]

try this

def pairs(l, n):
    return zip(*[l[i::n] for i in range(n)])

So,

pairs([1, 2, 3, 4], 2)
gives

[(1, 2), (3, 4)]
囍孤女 2024-09-04 22:06:29

正确的做法可能不是计算列表,而是编写迭代器->迭代器函数。这是更通用的——它适用于每个可迭代对象,如果您想将其“冻结”到列表中,可以使用“list()”函数。

def groupElements(iterable, n):
    # For your case, you can hardcode n=2, but I wanted the general case here.
    # Also, you do not specify what to do if the 
    # length of the list is not divisible by 2
    # I chose here to drop such elements
    source = iter(iterable)
    while True:
        l = []
        for i in range(n):
            l.append(source.next())
        yield tuple(l)

我很惊讶 itertools 模块还没有这样的功能——也许是未来的修订版。在那之前,请随意使用上面的版本:)

The right thing is probably not to compute lists, but to write an iterator->iterator function. This is more generic -- it works on every iterable, and if you want to "freeze" it into a list, you can use the "list()" function.

def groupElements(iterable, n):
    # For your case, you can hardcode n=2, but I wanted the general case here.
    # Also, you do not specify what to do if the 
    # length of the list is not divisible by 2
    # I chose here to drop such elements
    source = iter(iterable)
    while True:
        l = []
        for i in range(n):
            l.append(source.next())
        yield tuple(l)

I'm surprised the itertools module does not already have a function for that -- perhaps a future revision. Until then, feel free to use the version above :)

以可爱出名 2024-09-04 22:06:29

toolz 是一个构建良好的库,其中有许多在 itertools 中被忽略的函数式编程细节。 partition 解决了这个问题(可以选择填充奇数长度列表的最后一个条目)

>>> list(toolz.partition(2, [1,2,3,4,5,6]))
[(1, 2), (3, 4), (5, 6)]

toolz is a well-built library with many functional programming niceties overlooked in itertools. partition solves this (with an option to pad the last entry for lists of odd length)

>>> list(toolz.partition(2, [1,2,3,4,5,6]))
[(1, 2), (3, 4), (5, 6)]
空‖城人不在 2024-09-04 22:06:29

如果您不想丢失列表中元素的数量,请尝试以下操作:

>>> l = [1, 2, 3, 4, 5]
>>> [(l[i],  l[i+1] if i+1 < len(l) else None)  for i in range(0, len(l), 2)]
[(1, 2), (3, 4), (5, None)]

If you don't want to lose elements if their number in list is not even try this:

>>> l = [1, 2, 3, 4, 5]
>>> [(l[i],  l[i+1] if i+1 < len(l) else None)  for i in range(0, len(l), 2)]
[(1, 2), (3, 4), (5, None)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文