Python 从列表中创建元组或新列表
我有一个列表,它来自一个文本文件,我使用非常原始的正则表达式解析了该文件。我想重新组织一个更简洁的列表,其中只包含日期紧跟其后的文件。我尝试使用len()循环遍历列表,但这只会提取文件,而不会提取下一个条目。非常感谢 这: 变成这样:Python 从列表中创建元组或新列表,python,list,tuples,list-comprehension,Python,List,Tuples,List Comprehension,我有一个列表,它来自一个文本文件,我使用非常原始的正则表达式解析了该文件。我想重新组织一个更简洁的列表,其中只包含日期紧跟其后的文件。我尝试使用len()循环遍历列表,但这只会提取文件,而不会提取下一个条目。非常感谢 这: 变成这样: part002.csv.gz 2014-01-28 part001.csv.gz 2014-01-28 part002.csv.gz 2014-01-25 将前一行存储在每一行中,然后在需要时始终保留它 previous_line = None new
part002.csv.gz
2014-01-28
part001.csv.gz
2014-01-28
part002.csv.gz
2014-01-25
将前一行存储在每一行中,然后在需要时始终保留它
previous_line = None
newlist = []
for line in lines:
if isdate(line):
newlist.append(previous_line)
previous_line = line
定义isdate
:
import datetime
def isdate(s):
try:
datetime.datetime.strptime(s, '%Y-%m-%d')
except:
return False
else:
return True
通过它工作:
s = """
#that long string, snipped
"""
li = [x for x in s.splitlines() if x]
li
Out[3]:
['2014-01-28',
'part002.csv.gz',
'2014-01-28',
'part001.csv.gz',
'2014-01-28',
'2014-01-28',
'2014-01-27',
'2014-01-27',
'2014-01-26',
'2014-01-26',
'2014-01-25',
'part002.csv.gz',
'2014-01-25']
[tup for tup in zip(li,li[1:]) if 'csv' in tup[0]] #shown for dicactic purposes, gen expression used below
Out[7]:
[('part002.csv.gz', '2014-01-28'),
('part001.csv.gz', '2014-01-28'),
('part002.csv.gz', '2014-01-25')]
实际答案是:
from itertools import chain
list(chain.from_iterable(tup for tup in zip(li,li[1:]) if 'csv' in tup[0]))
Out[9]:
['part002.csv.gz',
'2014-01-28',
'part001.csv.gz',
'2014-01-28',
'part002.csv.gz',
'2014-01-25']
本质上:
zip
(在python2中,使用izip
)列表及其本身,一个索引高级。迭代两两元组,过滤掉第一个元素没有类似文件的字符串的元组。最后,使用itertools.chain
将元组展平到一个列表中,以获得所需的输出。您可以使用列表理解:
filtered = [e for i, e in enumerate(l) if not isDate(e) or (i > 0 and not isDate(l[i-1]))]
完整示例:
l = ['2014-01-28', 'part002.csv.gz', '2014-01-28', 'part001.csv.gz', '2014-01-28', '2014-01-28', '2014-01-27', 'part002.csv.gz', '2014-01-25']
def isDate (s):
return '.' not in s
filtered = [e for i, e in enumerate(l) if not isDate(e) or (i > 0 and not isDate(l[i-1]))]
print (filtered)
解释:
l
是我们的原始列表
isDate
获取一个字符串并测试它是否是日期(在我的简单示例中,它只是检查它是否不包含句点,为了获得更好的结果,请使用regex或strtime)
enumerate
枚举一个列表(或者任何可以列出的,我现在将坚持使用list
这个词,只是为了不太专业)。它返回一个元组列表;包含传递给enumerate的索引和列表元素的每个元组。例如枚举(['a',无,3])
使[(0,'a'),(1,无),(2,3)]
i,e=
解压元组,将索引分配给i
,将元素分配给e
列表理解的工作原理如下(简化):[x表示某处的x,如果条件为cond(x)]
返回符合条件cond(x)
的某处的所有元素的列表
在我们的例子中,我们只将元素添加到过滤列表中,如果它们不是日期(不是水果)不是isDate(e)
,或者如果它们不在开头i>0
,同时它们的前一个元素不是日期不是isDate(l[i-1])
(即文件)
在伪代码中:
Take list `l`
Let our filtered list be an empty list
For each item in `l` do
let `i` be the index of the item
let `e` be the item itself
if `e` is not a Date
or if `i` > 0 (i.e. it is not the first item)
and at the sametime the preceding item is a File
then and only then add `e` to our filtered list.
我将用一些解释来扩展我的答案。我添加了一些解释。
Take list `l`
Let our filtered list be an empty list
For each item in `l` do
let `i` be the index of the item
let `e` be the item itself
if `e` is not a Date
or if `i` > 0 (i.e. it is not the first item)
and at the sametime the preceding item is a File
then and only then add `e` to our filtered list.