【问题标题】:Return list of strings if any substring is present in another listPython - 如果另一个列表中存在任何子字符串,则返回字符串列表
【发布时间】:2021-07-31 02:42:36
【问题描述】:

假设您有这样的公司信息:

companies = [['zmpEVqsbCUO1aXStxHkSVA', 'palms-car-wash'],
['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
['C0d5kzUx6C19mLcxQyhxCA', 'alamo-drafthouse-cinema-'],
['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

假设您想要排除某些业务,如果列表(下面)的任何字符串/子字符串出现在上面列表的某些信息中:

no_interest = ['museum', 'cinema', 'car']

我已经这样做了,(我们只查看每个条目的第二列):

# KEEPING ONLY RESULTS WHERE WE DO NOT FIND THE SUBSTRINGS
[x for x in companies if (no_interest[0] not in x[1]) & (no_interest[1] not in x[1]) & (no_interest[2] not in x[1])]

# RETURN
[['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
 ['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

即使我希望它使用“OR”语句而不是“AND”(&) 语句,它似乎也可以工作,这对我来说是一个累积运算符,如果满足所有条件('museum ', 'cinema' 和 'car' 在同一个字符串中)

所以我有两个问题:

  • 为什么“AND”语句的作用类似于“OR”?
  • 我们如何才能使这段代码更 Python 和更高效?

我们在这里只检查 3 个子字符串,但我们正在寻找越来越多的数以千计的发生率,最好不要重复这些条件,但更像是 all()any() 语句返回结果而不是布尔值。

【问题讨论】:

  • 你为什么用&而不是andand 是逻辑运算符,用于条件,& 是按位运算符,用于表达式。
  • 老实说,我不确定这两者之间的真正区别......我看了here 那些仍然不知道区别的人。

标签: python list substring any term


【解决方案1】:

为什么“AND”语句的作用类似于“OR”?

见:DeMorgan's Laws

我们如何才能使这段代码更 Python 和更高效?

更多pythonic:

一种选择是在单独的列表理解上使用all

companies = [['zmpEVqsbCUO1aXStxHkSVA', 'palms-car-wash'],
             ['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
             ['C0d5kzUx6C19mLcxQyhxCA', 'alamo-drafthouse-cinema-'],
             ['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

no_interest = ['museum', 'cinema', 'car']

out = [x for x in companies if all([ni not in x[1] for ni in no_interest])]
print(out)

或者notany:

out = [x for x in companies if not any([ni in x[1] for ni in no_interest])]
[['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
 ['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

更高效:

使用像pandas这样的库:

import pandas as pd

companies = [['zmpEVqsbCUO1aXStxHkSVA', 'palms-car-wash'],
             ['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
             ['C0d5kzUx6C19mLcxQyhxCA', 'alamo-drafthouse-cinema-'],
             ['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

df = pd.DataFrame(data=companies, columns=['id', 'val'])

no_interest = ['museum', 'cinema', 'car']

out = df[~df['val'].str.contains('|'.join(no_interest))]
print(out)

作为数据帧输出

                       id              val
1  5T0vKfIJWP1xTnxA7fJ17w   meat-and-bread
3  ch1ercqwoNLpQLxpTb90KQ  boston-tea-stop

输出为列表

print(out.to_numpy().tolist())
[['5T0vKfIJWP1xTnxA7fJ17w', 'meat-and-bread'],
 ['ch1ercqwoNLpQLxpTb90KQ', 'boston-tea-stop']]

【讨论】:

  • 哇,感谢您快速而完整的回答! Pandas 方法也很有趣。
【解决方案2】:

这是另一个使用正则表达式的例子,但(正如亨利埃克的熊猫回答)它假设在任何“no_interest”元素中都没有干扰正则表达式的特殊字符

import regex as re
pattern = re.compile("|".join(no_interest))
out = [c for c in companies if ((pattern.search(c[0]) == None) and (pattern.search(c[1]) == None))]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 2021-06-25
    • 2019-07-27
    • 2013-11-05
    相关资源
    最近更新 更多