Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从列表中创建元组或新列表_Python_List_Tuples_List Comprehension - Fatal编程技术网

Python 从列表中创建元组或新列表

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

我有一个列表,它来自一个文本文件,我使用非常原始的正则表达式解析了该文件。我想重新组织一个更简洁的列表,其中只包含日期紧跟其后的文件。我尝试使用len()循环遍历列表,但这只会提取文件,而不会提取下一个条目。非常感谢

这:

变成这样:

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.