124

所以我想创建一个列表,它是一些现有列表的子列表。

例如,

L = [1, 2, 3, 4, 5, 6, 7],我想创建一个子列表li,其中li包含奇数位置的所有元素L

虽然我可以做到

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

但我想知道是否有另一种方法可以有效地以更少的步骤完成相同的操作。

4

4 回答 4

285

解决方案

是的你可以:

l = L[1::2]

这就是全部。结果将包含放置在以下位置的元素(0基于 -,所以第一个元素在 position 0,第二个在1等):

1, 3, 5

所以结果(实际数字)将是:

2, 4, 6

解释

最后[1::2]的只是列表切片的符号。通常它是以下形式:

some_list[start:stop:step]

如果我们省略start,将使用默认值 ( 0)。因此将选择第一个元素(在 position 0,因为索引是0基于 - 的)。在这种情况下,将选择第二个元素。

因为省略了第二个元素,所以使用默认值(列表的末尾)。所以列表正在从第二个元素迭代到 end

我们还提供了第三个参数 ( step),即2. 这意味着将选择一个元素,跳过下一个元素,依此类推......

所以,总而言之,在这种情况下[1::2]意味着:

  1. 取第二个元素(顺便说一下,如果你从索引判断,它是一个奇怪的元素),
  2. 跳过一个元素(因为我们有step=2,所以我们跳过一个,与step=1默认值相反),
  3. 取下一个元素,
  4. 重复步骤 2.-3。直到到达列表的末尾,

编辑:@PreetKukreti 给出了关于 Python 列表切片符号的另一个解释的链接。见这里:解释 Python 的切片符号

附加功能 - 将 counter 替换为enumerate()

在您的代码中,您明确创建并增加计数器。在 Python 中,这不是必需的,因为您可以通过一些可迭代的 using 进行枚举enumerate()

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

上面的用途与您使用的代码完全相同:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

for有关在 Python 中使用计数器模拟循环的更多信息: Accessing the index in Python 'for' loops

于 2012-09-15T01:08:49.920 回答
13

对于奇数职位,您可能想要:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>
于 2012-09-15T01:30:04.403 回答
7

我喜欢列表推导,因为它们的数学(集合)语法。那么这个怎么样:

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

基本上,如果你枚举一个列表,你会得到 indexx和 value y。我在这里所做的是将值y放入输出列表(偶数或奇数)并使用索引x来确定该点是否为奇数(x%2 != 0)。

于 2016-08-24T14:02:52.567 回答
0

您可以使用按位 AND 运算符&

>>> x = [1, 2, 3, 4, 5, 6, 7]
>>> y = [i for i in x if i&1]
[1, 3, 5, 7]

这将为您提供列表中的奇数元素。现在要提取奇数索引处的元素,您只需要稍微更改一下上面的内容:

>>> x = [10, 20, 30, 40, 50, 60, 70]
>>> y = [j for i, j in enumerate(x) if i&1]
[20, 40, 60]

解释

按位与运算符与 1 一起使用,它起作用的原因是,以二进制形式写入的奇数必须有它的第一个数字为 1。让我们检查一下:

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

与 1 的 AND 操作将仅返回 1(二进制中的 1 也将具有最后一位 1),如果该值是奇数。

查看 Python位运算符页面了解更多信息。

PS:如果你想在数据框中选择奇数列和偶数列,你可以战术上使用这种方法。假设面部关键点的 x 和 y 坐标以 x1、y1、x2 等列的形式给出...要使用每个图像的宽度和高度值标准化 x 和 y 坐标,您可以简单地执行:

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

这与问题并不完全相关,但对于数据科学家和计算机视觉工程师来说,这种方法可能很有用。

于 2020-03-16T09:36:53.163 回答