遍历嵌套列表并计算特定值

时间:2019-02-13 15:08:26

标签: python

我有这个嵌套列表:

d = ['good morning', 'hello', 'chair', 'python', ['music', 'flowers', 
    'facebook', 'instagram', 'snapchat', ['On my Own', 'monster', 'Words 
     dont come so easily', 'lead me right']], 'Stressed Out', 'Pauver 
     Coeur', 'Reach for Tomorrow', 'mariners song', 'Wonder sleeps here']

我需要遍历列表,以便如果字符串中有字符“ m”,则应将其添加到名为m_list的新列表中。

到目前为止,我尝试过以下操作:

m_list = []
for el in d:
    print(" Level1: {}".format(el))
    if type(el) is str:
        if 'm' in el:
            m_list.append(el)
    for el2 in el:
        print(" Level2: {}".format(el2))
        if type(el2) is str:
            if 'm' in el2:
                m_list.append(el2)
        for word in el2:
            print(" Level3: {}".format(word))
            if type(word) is str:
                if 'm' in word:
                   m_list.append(word)

我知道我没有正确设置代码,因为内部循环会重复计算某些元素。 例如:

print(m_list)

['good morning', 'm', 'm', 'music', 'm', 'instagram', 'm', 'On my Own', 
'monster', 'Words dont come so easily', 'lead me right', 'Reach for 
Tomorrow', 'm', 'm', 'mariners song', 'm', 'm']

我使用效率低下的代码解决了这个问题:

s = set(m_list)
m_list = list(s)
m_list.remove('m')
print(m_list) 
['monster', 'mariners song', 'Words dont come so easily', 'Reach for 
Tomorrow', 'On my Own', 'lead me right', 'music', 'good morning', 
'instagram']

我的问题是如何更改循环以正确计算字符'm'并分配给 m_list

P.S。我不是Python的熟练用户。我想提高自己的技能。您想建议我更聪明的方法吗?

6 个答案:

答案 0 :(得分:3)

您可以创建一个通用的自定义函数,如果其中包含列表,则将调用自身;如果其中包含'm',则将值追加到新列表中:

d = ['good morning', 'hello', 'chair', 'python', ['music', 'flowers', 
    'facebook', 'instagram', 'snapchat', ['On my Own', 'monster', 'Words  dont come so easily', 'lead me right']], 'Stressed Out', 'Pauver Coeur', 'Reach for Tomorrow', 'mariners song', 'Wonder sleeps here']

def find_all_values(d, m, m_list=[]):
    for x in d:
        if isinstance(x, list):
            find_all_values(x, m, m_list)
        elif m in x:
            m_list.append(x) 
    return m_list


m_list = find_all_values(d, 'm')
# ['good morning', 'music', 'instagram', 'On my Own', 'monster', 'Words  dont come so easily', 'lead me right', 'Reach for Tomorrow', 'mariners song']

m_list_count = len(m_list)
# 9

现在有了通用的自定义函数,您可以使用它来创建一个列表,该列表保存包含任何字母的值并获取其计数。

答案 1 :(得分:2)

如果不确定嵌套的深度,则需要采用如下递归方法:

def find_char(char, words):
        result = []
        for word in words:
          if isinstance(word,list):
            result += find_char(char,word)
          else:
            if char in word:
              result.append(word)
        return result

>>> d = ['good morning', 'hello', 'chair', 'python', ['music', 'flowers',
'facebook', 'instagram', 'snapchat', ['On my Own', ['monster'], 'Words don`t come so easily', 'lead me right']], 'Stressed Out', 'Pauver Coeur', 'Reach for Tomorrow', 'mariners song', 'Wonder sleeps here']

>>> find_char("m",d)
['good morning', 'music', 'instagram', 'On my Own', 'monster', 'Words don`t come so easily', 'lead me right', 'Reach for Tomorrow', 'mariners song']

无论列表嵌套的深度如何,此方法都可以使用。

答案 2 :(得分:0)

如果元素是字符串,则需要告诉内部for循环不要运行。适用于您的案例的常见方式有两种:

  1. 在前面的else上添加if子句并缩进for循环。转换为“如果元素不是字符串,则仅运行此代码 ”:

    if type(el) is str:
        if 'm' in el:
            m_list.append(el)
    else:
        for el2 in el:
            ...
    
  2. 如果元素是字符串,则添加continue语句。转换为“如果有字符串,请不要执行其他任何操作”:

    if type(el) is str:
        if 'm' in el:
            m_list.append(el)
        continue
    for el2 in el:
    

我个人比较喜欢第一个版本,因为它更明确。同时,第二个版本在其余代码中为您节省了一定程度的缩进,这也非常好。

答案 3 :(得分:0)

尝试一下:

m_list = []
for el in d:   
    if type(el) is str:
        if 'm' in el:
            m_list.append(el)
    else:
        for el2 in el:   
            if type(el2) is str:
                if 'm' in el2:
                    m_list.append(el2)
            else:
                for word in el2:
                    if type(word) is str:
                        if 'm' in word:
                           m_list.append(word)

print(m_list)

答案 4 :(得分:0)

这是一个递归解决方案

data = ['good morning', 'hello', 'chair', 'python', ['music', 'flowers', 'facebook', 'instagram', 'snapchat',
                                                 ['On my Own', 'monster', 'Words dont come so easily',
                                                  'lead me right']], 'Stressed Out', 'Pauver Coeur',
    'Reach for Tomorrow', 'mariners song', 'Wonder sleeps here']

m_holder = []


def m_finder(lst, m_holder):
    for word_or_list in lst:
        if isinstance(word_or_list, str):
            if 'm' in word_or_list:
                m_holder.append(word_or_list)
        else:
            m_finder(word_or_list, m_holder)


m_finder(data, m_holder)
print(m_holder)

输出:

['good morning', 'music', 'instagram', 'On my Own', 'monster', 'Words dont come so easily', 'lead me right', 'Reach for Tomorrow', 'mariners song']

答案 5 :(得分:0)

在Python 3中:

def myflatten(l):
    for elem in l:
        if isinstance(elem, list):
            yield from myflatten(elem)
        else:
            if 'm' in elem:
                yield elem

list(myflatten(d))