【问题标题】:Using slicing in loops在循环中使用切片
【发布时间】:2018-06-21 16:51:32
【问题描述】:

我正在从列表中写入一个文件。该列表包含波长和计数。如下图所示:

list = ['300','5','400','7','500','4']

我想要做的是将这些元素写入文件,以便第一列是波长条目,第二列是计数条目。

我的解决方法如下:

file = open("prøve_fil.TXT","w")

index = 0
while index <= len(lines):
    file.write(lines[index]+'\t'+lines[index+1]+'\n')
    index += 1

现在,我知道此方法将到达列表末尾,然后尝试查找 index+1 并由于列表边界而返回错误。第二件事是,一行中的每个最后一个条目都成为下一行的第一个条目,因此文件将如下面的示例所示:

'300' '5' '5' '400' '400' '7' '7' '500' '500' '4'

我认为也许某种切片是我的解决方案,但我无法真正只见树木不见森林。

【问题讨论】:

  • 2 增加index,而不是1
  • 增加两个并没有多大帮助。这将每隔一条线作为波长或计数,因此它变为:'300''400''5''7'
  • index += 2 应该修复它。

标签: python indexing while-loop slice file-writing


【解决方案1】:

使用zip 进行切片:

>>> for x,y in zip(data[::2], data[1::2]):
...     print(f"{x}\t{y}")
...
300 5
400 7
500 4
>>>

或者你可以使用这种厚颜无耻的结构*:

>>> for x,y in zip(*[iter(data)]*2):
...     print(f"{x}\t{y}")
...
300 5
400 7
500 4

以上内容应该让您体验到 Python 提供的大量迭代构造。但是,我建议坚持使用基本的循环结构,例如:

>>> for i in range(0, len(data) - 1, 2):
...     print(data[i],data[i+1])
...
300 5
400 7
500 4

注意,学习更喜欢 for 循环而不是 while 循环。一旦掌握了它们,它们就不容易出错。您可以使用range 做很多事情。但是,这是等效的 while 循环:

i = 0
while i < len(data) - 1:
    print(data[i], data[i+1])
    i += 2

*注意,虽然我通常不使用这种神秘的东西,因为我看重可读性和简单性,但它是一种经典的 Python 主义。可以这样概括:

>>> def iter_by_n(iterable, n):
...     return zip(*[iter(iterable)]*n)
...
>>> list(iter_by_n(range(9), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

但是,它只会给你直到最后一个完整的部分:

>>> list(iter_by_n(range(10), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
>>> list(iter_by_n(range(11), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
>>> list(iter_by_n(range(12), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]

这通常是您想要的行为,但您也可以使用 itertools.zip_longest 使用您想要的任何默认值填写分区:

>>> from itertools import zip_longest
>>> def iter_by_n(iterable, n, fillvalue=None):
...     return zip_longest(*[iter(iterable)]*n, fillvalue=fillvalue)
...
>>> list(iter_by_n(range(10), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
>>> list(iter_by_n(range(10), 3, fillvalue='FOO'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 'FOO', 'FOO')]
>>> list(iter_by_n(range(11), 3, fillvalue='FOO'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 'FOO')]
>>> list(iter_by_n(range(12), 3, fillvalue='FOO'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
>>>

【讨论】:

  • 虽然解决方案是正确的 Pythonic 解决方案,但我想说,在这种情况下,它只会混淆 OP,或者让他只是在不理解代码的情况下剪切粘贴代码。 OP 正在为基本的索引迭代而苦苦挣扎。
  • 是的!非常感谢!
  • @imanolLuengo 我想我已经切入了。我一直在努力将其实现为循环。
【解决方案2】:

试试这个方法,作为代码的更新:

lines = ['300','5','400','7','500','4']
index = 0
while index <= (len(lines) -2):
    print(lines[index] + "\t" + lines[index+1] + "\n")
    index += 2

所以你得到:

300 5

400 7

500 4

【讨论】:

    猜你喜欢
    • 2021-03-28
    • 2013-09-26
    • 2018-06-06
    • 1970-01-01
    • 2012-10-16
    • 2020-08-02
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多