在奇数位置提取 list 元素

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

比如说,

我希望创建一个子列表 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

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

184368 次浏览

解决方案

是的,你可以:

l = L[1::2]

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

1, 3, 5

因此,结果(实际数字)将是:

2, 4, 6

解释

最后的 [1::2]只是一个表示列表切片的符号,通常采用以下形式:

some_list[start:stop:step]

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

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

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

因此,总的来说,在这种情况下,[1::2]意味着:

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

编辑 :@PreetKukreti 给出了另一个关于 Python 片段符号列表的解释的链接。请参阅这里: < a href = “ https://stackoverflow.com/questions/509211/good-primer-for-Python-slice-note”> 解释 Python 的片段符号

enumerate()代替计数器

在代码中,显式创建并增加计数器。在 Python 中,这是不必要的,因为您可以使用 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

更多关于在 Python 中使用计数器模拟 for循环的信息: 访问 Python 中的索引 for & # 39; 循环

对于 奇怪的职位,你可能需要:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

我喜欢 List 的理解,因为它们的 Math (Set)语法:

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]

基本上,如果枚举一个列表,就会得到索引 x和值 y。我在这里所做的是将值 y放入输出列表(偶数或奇数) ,并使用索引 x查找该点是否为奇数(x%2 != 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]

解释

按位 AND 运算符与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

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