【问题标题】:Simplifying a list filter in Python在 Python 中简化列表过滤器
【发布时间】:2015-11-07 21:36:48
【问题描述】:

我正在尝试过滤由多个字典组成的列表以查找无用条目和非理想字段。如果Mem['visibility'] == "redacted" 则条目是无用的,然后应该从列表中删除。当任何字段为空时,条目是不理想的,应该用 0 填充,或者如果 Mem['~whatever~'] 是一个列表,在这种情况下,列表应该转换为包含该列表中所有对象的单个字符串.为此,我编写了以下代码:

class Filter:

    @staticmethod
    def members(memberlist):
        for Mem in memberlist:
            for Item in Mem:
                if not Mem[Item]:
                    Mem[Item] = 0
                if (type(Mem[Item]) is list):
                    Mem[Item] = ', '.join(Mem[Item])
            if(Mem['visibility'] == "redacted"):
                memberlist.remove(Mem)
        return(memberlist)

成员列表示例:

[
    {'roles': [],
     'rank': 'No SCB account',
     'type': 'main',
     'stars': 2,
     'visibility': 'visible',
     'sid': 'imperium',
     'handle': 'freakyeagle'
    },
    {'roles': [],
     'rank': 'Fleet Member',
     'type': 'main',
     'stars': 1,
     'visibility': 'visible',
     'sid': 'imperium',
     'handle': 'cadimus'},
    {'roles': [],
     'rank': 'Fleet Member',
     'type': 'main',
     'stars': 1,
     'visibility': 'visible',
     'sid': 'imperium',
     'handle': 'belleal'}
]

我怎样才能使它尽可能简单/高效?

另外,由于某种原因,当我从上面代码的列表中删除无用的 Mem 时,它会破坏我在以下函数中发生的数据库插入(上面函数中的 memberlist 相当于这个函数中的 member):

def member(conn, cursor, member):
    try:
        if type(member) is not list:
            # TODO: Eventually implement single member insert here.
            print(member)
        cursor.executemany("INSERT INTO `Citizens` (`Handle`,`Org`,`Role`, "
                           "`Rank`,`Visibility`,`Stars`,`Type`) VALUES "
                           "(%(handle)s,%(sid)s,%(roles)s,%(rank)s,"
                           "%(visibility)s,%(stars)s,%(type)s);", member)
        conn.commit()

有人知道为什么会这样吗?

【问题讨论】:

  • 顺便说一句,当您遍历列表时,切勿从列表中删除项目 - 由于列表中的某些项目被跳过,这会产生意想不到的结果。
  • 最好的方法是什么?创建一个要删除的 Mem 列表,然后再将其删除?
  • 要么遍历列表的副本 (for mem in memberlist[:]:),要么将您确实想要保留的列表追加到新列表中并返回。
  • 只是一个注释;如果Mem[Item] 是一个空列表,您将把它转换为0,因为if not Mem[Item]: 为空列表返回True。
  • 如果您没有错误或问题,并且您所追求的只是您的代码是否高效,那么最好在codereview.stackexchange.com 上询问:-)

标签: python list filter generator


【解决方案1】:

您不应该在迭代列表时从列表中删除项目 - 在删除项目后跳过项目时会出现意外行为。

相反,制作列表的副本以进行迭代:

for mem in memberlist[:]:
    ...

或者将您想要的结果保存到另一个列表并返回:

keep = []
for mem in memberlist:
    if ...:
       keep.append(mem)
return keep

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多