从Python列表中删除日期

3

我有一些包含字符串的列表,我想从这些字典中删除一些字符串日期,例如“2017-09-11”、“2017-09-17”、“2015-09-11”。我该怎么做?

WNT5 = ['RBPMS', 'TRIM2', 'GPM6A', 'TACC1', '2017-09-06', 'PARVA', 'RPS28', 'MAN1C1', 'LOXL2', 'PTPRB', 'STAG2', 'SFRS15', 'PDS5B', 'SWAP70', 'ZMIZ2', 'TPD52', 'OGT', 'RSU1', 'TGFBR3', 'NFAT5', 'ANGPT1', 'SLC25A36', 'NFIB', 'FBXO9', 'N4BP2L2', 'CCDC69', 'MYH11', 'LPP', 'USP34', 'ITIH5', 'GLS', 'SORBS2', 'TMEM43', 'ANK3', 'PSIP1', 'SYNPO2', 'C9orf5', 'BCL2', 'NSMAF', 'MLXIP', 'PDE8B', 'RABGAP1', 'RPS15A', 'NLRP12', 'AKAP1', 'PLK1S1', 'SLC4A4', 'COBLL1', 'ARHGEF7', 'CD47', 'TMEM132A', 'TNK2', 'WWC1', 'RPL22', 'NMT2', 'TNXB', 'SCPEP1', 'TTLL5', 'MAGI1', 'GOLGA2B', 'TIMELESS', 'ITPR1', 'ALMS1', 'TLE2', 'MAPT', 'DIP2A', 'PCGF3', 'CYP3A4', 'RALGPS1', 'N4BP2L1', 'DIO2', 'PPP1R3C', 'LRIG1', 'NSMCE4A', 'GPX2', 'SETBP1', 'SLC6A16', 'ARL5A']

4
它们是字典还是列表?你提供的例子是一个字符串列表,而不是字典。 - cosinepenguin
编辑过了,非常感谢。 - Ajml
6个回答

2
使用列表推导式,您将获得一个新的列表,其中不包含日期字符串:
>>> def is_date_string(s):
...     # return re.search(r'^\d{4}-\d{2}-\d{2}$')
...     return '-' in s and s[:4].isdigit()  # NOTE not perfect, change as you need
... 
>>> [s for s in WNT5 if not is_date_string(s)]
['RBPMS', 'TRIM2', 'GPM6A', 'TACC1', 'PARVA', 'RPS28',
 'MAN1C1', 'LOXL2', 'PTPRB', 'STAG2', 'SFRS15', 'PDS5B', 'SWAP70',
 'ZMIZ2', 'TPD52', 'OGT', 'RSU1', 'TGFBR3', 'NFAT5', 'ANGPT1',
 'SLC25A36', 'NFIB', 'FBXO9', 'N4BP2L2', 'CCDC69', 'MYH11', 'LPP',
 'USP34', 'ITIH5', 'GLS', 'SORBS2', 'TMEM43', 'ANK3', 'PSIP1',
 'SYNPO2', 'C9orf5', 'BCL2', 'NSMAF', 'MLXIP', 'PDE8B', 'RABGAP1',
 'RPS15A', 'NLRP12', 'AKAP1', 'PLK1S1', 'SLC4A4', 'COBLL1', 'ARHGEF7',
 'CD47', 'TMEM132A', 'TNK2', 'WWC1', 'RPL22', 'NMT2', 'TNXB',
 'SCPEP1', 'TTLL5', 'MAGI1', 'GOLGA2B', 'TIMELESS', 'ITPR1', 'ALMS1',
 'TLE2', 'MAPT', 'DIP2A', 'PCGF3', 'CYP3A4', 'RALGPS1', 'N4BP2L1',
 'DIO2', 'PPP1R3C', 'LRIG1', 'NSMCE4A', 'GPX2', 'SETBP1', 'SLC6A16',
 'ARL5A']

要替换 WNT5,请将列表推导式重新分配回去:
WNT5 = [s for s in WNT5 if not is_date_string(s)]

或者使用切片(就地替换项目):
WNT5[:] = [s for s in WNT5 if not is_date_string(s)]

1
你的输出的第五个元素是一个日期字符串,所以我敢说可能有些地方不太对。 - Brad Solomon
@BradSolomon,我贴错了输出。我已经修复了。谢谢你的反馈。 - falsetru
最好将其分配给列表切片。在这里阅读:https://dev59.com/p3M_5IYBdhLWcg3w1G6N#1208792 - technusm1
@BradSolomon,将 return '-' in s and s[:4].isdigit() 替换为 return '-' in s and s[:2].isdigit() 将处理这种情况。但当前的代码足以处理 *'2017-09-11', '2017-09-17', '2015-09-11'*。 - falsetru
1
@Nguyen,列表推导式不会改变列表,但会返回一个新的列表。你应该将结果赋值回linklink = [s for s in link if not is_date_string(s)]或者link[:] = [s for s in link if not is_date_string(s)] - falsetru
显示剩余3条评论

1

要从列表中删除,您可以使用以下删除语句:

WNT5.remove('b')

这将删除该元素(“b”)的第一次出现。要删除所有元素,您可以使用列表推导。

>>> WNT5 = [x for x in WNT5 if len(x) != 10]
>>> print(WNT5)

这里假设长度为10的字符串只有日期字符串。
希望能对您有所帮助!
编辑:
我回答得有点晚,其他人已经给出了更好的答案,但我在另一个SO问题中也发现了这个函数,可能会有用。
from dateutil.parser import parse
def is_date(string):
    try: 
        parse(string)
        return True
    except ValueError:
        return False

然后你有一个函数可以运行,以确保你排除的字符串只是日期(以任何格式)

示例:

>>> is_date("1990-12-1")
    True
>>> is_date("xyznotadate")
    False
>>> WNT5 = [x for x in WNT5 if not is_date(x)]
>>> print(WNT5)

0
问题没有完全说明,但我认为解释如何像列表一样操作字典可能就足够了,即使您在问题中指定了一个列表。
mydict = {'2017-04-11':22, '2017-04-12':23, '2017-04-13': 128}
newkeys = list(mydict.keys())
newkeys.remove('2017-04-12')
newvals = [mydict[keptkey] for keptkey in newkeys]
newdict = dict(zip(newkeys, newvals))

一旦您获得了新的键列表,您可以按任何方式截取其中的元素。


0
import datetime
nwnt = len(WNT5)
for k, s in enumerate(reversed(WNT5)):
    try:
        datetime.datetime.strptime(s, '%Y-%m-%d') # adjust format to your liking
        del WNT5[nwnt - k - 1]
    except ValueError:
        pass

-1

正如其他人所指出的,使用循环遍历列表并调用remove()并不是最佳选项。因此,你可以采取以下方法:

使用list(original_list)迭代一个副本:

# makes a copy of the list to iterate rather than original
for item in list(WNT5):
    # assumes dates are yyyy-mm-dd and all contain the '-'
    # split() returns a list object
    # it will only split the '-' if its there, wont error
    if (len(item) == 10) and (len(item.split('-')) == 3):
        WNT5.remove(item)

通过列表推导式创建一个过滤列表:

def is_not_date(WNT5):
    for item in WNT5:
        if not ((len(item) == 10) and (len(item.split('-')) == 3)):
            yield item    

new_WNT5 = [x for x in is_not_date(WNT5)]

可能有更符合Python风格的方法来完成这个任务(也许可以使用datetime?)

说实话,我们需要更多的信息才能提供解决方案:

  • 它们都是相同的格式吗?
  • 它们都是字符串吗?
  • 问题的范围是什么?

1
在迭代列表时删除列表项并不起作用。 - falsetru
https://dev59.com/p3M_5IYBdhLWcg3w1G6N - falsetru
不必进行分割,可以使用计数;item.count('-') == 2 - falsetru
我已经通过注释解释了原因。顺便说一句,在你的编辑之后,我撤回了我的踩票。 - falsetru
顺便提一下,“is_not_date”这个函数名对于过滤函数来说有点奇怪。它听起来像是谓词。 - falsetru
显示剩余8条评论

-1

你也可以尝试使用正则表达式的方法:

import re
result_list = [element for element in WNT5 if re.search("[0-9]{4}\-[0-9]{2}\-[0-9]{2}", element) is None]

如果需要,您可以使用这种方法添加更多日期模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接