了解 python 转置脚本
Understanding python transposing script
我找到了一个名为 transpose_file.py 的 Python 脚本,它可以转置 space 分隔的文件。看起来是这样的:
import fileinput
m = []
for line in fileinput.input():
m.append(line.strip().split(" "))
for row in zip(*m):
print " ".join(row)
我想确保我理解每一行的作用,因为我是 Python 的新手。
1) 首先,我们导入一个名为 fileinput 的模块,它允许您读取文件并解析它们?不知道为什么使用简单的 with open(sys.argv[1],'r') as f 等不起作用
2) 创建一个名为 m
的空列表
3) 对于输入文件中的每一行,去掉行尾的任何 space、制表符或换行符,并使 space 成为分隔符(即您的输入文件被分隔)
4) 对于每一行...不确定其余部分的含义。 zip(*m) 是什么意思?完成后,我们打印 space 并加入该行?我只是不明白这是如何导致换位的。
任何解释将不胜感激。
你的分析基本正确
请注意
line.strip().split(" ")
有点脆弱。它从该行中去除所有前导和尾随的白色 space,然后将该行拆分为一个字符串列表,使用单个 space 作为分隔符。如果该行包含多个运行 space,或者包含制表符,这可能无法满足您的要求。
zip
函数并行迭代其参数,从每个参数中的相应项目构建元组。所以首先它生成一个包含所有第一个项目的元组,然后是所有第二个项目,等等。
例如:
for t in zip([1, 2, 3], [4, 5, 6], [7, 8, 9]):
print(t)
print()
输出
(1, 4, 7)
(2, 5, 8)
(3, 6, 9)
如您所见,这会导致换位。
我们可以使用 *
"splat" 运算符将序列列表传递给 zip
,"splat" 运算符解压缩列表,以便 zip
将这些序列中的每一个视为一个单独的参数。
lst = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for t in zip(*lst):
print(t)
这给出了与以前相同的输出。
"splat" 运算符不仅仅是 zip
的一个特殊功能:您可以在任何接受多个参数的函数上使用它。还有 "double-splat" 运算符 **
,它将字典解包为关键字=值对。
如果序列的长度不同,那么 zip
在最短序列中没有更多项目时停止。但是,标准 itertools
模块中有一个相关函数:itertools.zip_longest
,它采用可选的 fillvalue
。它一直持续到最长的序列用完,使用 fillvalue
来填补空白。默认的 fillvalue
是 None
.
关于fileinput
,有些人只是觉得方便,我更喜欢with open(
...
fileinput
也支持其他的文件输入方式。它可以有效地做到 open(sys.argv[1],'r')
,但也支持其他可能性 - 请参阅 Python documentation。
您对 2 和 3 的理解大致正确
对于每一行,该行被去除白色space,然后被space分割。这会生成一个网格,代表文件的每个 space 分隔部分。
zip(*)
实际上是 Python 的转置运算符。例如:
In [1]: data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [2]: data
Out[2]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [3]: transp = list(zip(*data))
In [4]: transp
Out[4]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
您必须将其强制转换为 list
作为 zip
returns 可迭代对象。 zip
可能更常用于 "zip" 两个列表,因此您可以一起迭代它们:
In [1]: list(zip(["one", "three", "five"], ["two", "four", "six"]))
Out[1]: [('one', 'two'), ('three', 'four'), ('five', 'six')]
这个也不错documented.
*
运算符将网格的每个子列表分隔为 zip
的单独参数。
" ".join
用 space 将每个字符串连接到一个可迭代对象中 - 例如
In [1]: " ".join(["foo", "bar", "baz"])
Out[1]: 'foo bar baz'
这只是将 space 定界符放回新转置的字符串系列中。又是,documented.
我找到了一个名为 transpose_file.py 的 Python 脚本,它可以转置 space 分隔的文件。看起来是这样的:
import fileinput
m = []
for line in fileinput.input():
m.append(line.strip().split(" "))
for row in zip(*m):
print " ".join(row)
我想确保我理解每一行的作用,因为我是 Python 的新手。
1) 首先,我们导入一个名为 fileinput 的模块,它允许您读取文件并解析它们?不知道为什么使用简单的 with open(sys.argv[1],'r') as f 等不起作用
2) 创建一个名为 m
的空列表3) 对于输入文件中的每一行,去掉行尾的任何 space、制表符或换行符,并使 space 成为分隔符(即您的输入文件被分隔)
4) 对于每一行...不确定其余部分的含义。 zip(*m) 是什么意思?完成后,我们打印 space 并加入该行?我只是不明白这是如何导致换位的。
任何解释将不胜感激。
你的分析基本正确
请注意
line.strip().split(" ")
有点脆弱。它从该行中去除所有前导和尾随的白色 space,然后将该行拆分为一个字符串列表,使用单个 space 作为分隔符。如果该行包含多个运行 space,或者包含制表符,这可能无法满足您的要求。
zip
函数并行迭代其参数,从每个参数中的相应项目构建元组。所以首先它生成一个包含所有第一个项目的元组,然后是所有第二个项目,等等。
例如:
for t in zip([1, 2, 3], [4, 5, 6], [7, 8, 9]):
print(t)
print()
输出
(1, 4, 7)
(2, 5, 8)
(3, 6, 9)
如您所见,这会导致换位。
我们可以使用 *
"splat" 运算符将序列列表传递给 zip
,"splat" 运算符解压缩列表,以便 zip
将这些序列中的每一个视为一个单独的参数。
lst = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for t in zip(*lst):
print(t)
这给出了与以前相同的输出。
"splat" 运算符不仅仅是 zip
的一个特殊功能:您可以在任何接受多个参数的函数上使用它。还有 "double-splat" 运算符 **
,它将字典解包为关键字=值对。
如果序列的长度不同,那么 zip
在最短序列中没有更多项目时停止。但是,标准 itertools
模块中有一个相关函数:itertools.zip_longest
,它采用可选的 fillvalue
。它一直持续到最长的序列用完,使用 fillvalue
来填补空白。默认的 fillvalue
是 None
.
关于fileinput
,有些人只是觉得方便,我更喜欢with open(
...
fileinput
也支持其他的文件输入方式。它可以有效地做到open(sys.argv[1],'r')
,但也支持其他可能性 - 请参阅 Python documentation。您对 2 和 3 的理解大致正确
对于每一行,该行被去除白色space,然后被space分割。这会生成一个网格,代表文件的每个 space 分隔部分。
zip(*)
实际上是 Python 的转置运算符。例如:In [1]: data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] In [2]: data Out[2]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] In [3]: transp = list(zip(*data)) In [4]: transp Out[4]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
您必须将其强制转换为
list
作为zip
returns 可迭代对象。zip
可能更常用于 "zip" 两个列表,因此您可以一起迭代它们:In [1]: list(zip(["one", "three", "five"], ["two", "four", "six"])) Out[1]: [('one', 'two'), ('three', 'four'), ('five', 'six')]
这个也不错documented.
*
运算符将网格的每个子列表分隔为zip
的单独参数。" ".join
用 space 将每个字符串连接到一个可迭代对象中 - 例如In [1]: " ".join(["foo", "bar", "baz"]) Out[1]: 'foo bar baz'
这只是将 space 定界符放回新转置的字符串系列中。又是,documented.