过滤字符串中的特定单词以获取特定关键字以在 python 中进行 if 语句

Filter specific words in a string to get a specific keyword to make an if statement in python

我目前正在做一个项目,我现在的任务是我需要根据Bands列中给出的Bands指定设备是否为2G。例如,

Device ID |Bands|2G(New added column)
123 |GSM 1800, GSM 700 |                                            
124 | GSM 1800, GSM 700, GSM 1, LTE TDD |                            
125 | TD-SCDMA,1 SIM |                                              
126 |GSM850 (GSM800),WCDMA FDD Band I,WCDMA FDD Band VIII,2 SIM |

因此,如果 "Bands" 列仅包含单词 "GSM" 那么它是 2G,否则,N。

我试过使用 re 模块,但在某些时候卡住了。

import re
import csv
...
two_G_only = []
...
with open('filepath.txt', "rU") as f:
    reader = csv.DictReader(f, delimiter = "|")
    for row in reader:
        ...
        ...
        if 'GSM' in row['Bands']:
        gsm_only = " ".join(re.findall("[a-zA-Z]+", row['Bands']))
        #Im stuck at here because I don't know how to test whether there is only GSM or else          
    else:
        two_G_only.append('N')
        ...
        ...

结果需要什么

Device ID | Bands | 2G
123 | GSM 1800, GSM 700 | Y
124 |GSM 1800, GSM 700, GSM 1, LTE TDD | N
125 |TD-SCDMA,1 SIM | N
126 |GSM850 (GSM800),WCDMA FDD Band I,WCDMA FDD Band VIII,2 SIM|N

提前谢谢你,如果我的问题不明白,请发表评论。我已经搜索了网站中给出的一些解决方案,但我确定提出的问题不一样 problematic/concept.

您显示的数据用制表符或空格分隔成列,但您的代码表明您使用竖线 (|) 作为分隔符。我不确定哪个是对的,但那是你的问题。

据我了解,您的条件是查看第二列中的各个子字段,以逗号分隔,并且 return 如果每个子字段都包含子字段中任意位置的文本字符串 'GSM',但如果至少有一个子字段不包含该字符串,则为 return 不同的值 (false)。对吗?

让我们假设您的 csv reader 在 reader 中,如您的示例所示。 for-row-in 循环是正确的,因为您想对每一行分别进行此计算。

for row in reader:

在该循环中,您需要访问 Bands 列:

    bands = row['Bands']

为了检查子字段,让我们使用基本的 str.split 函数,用逗号分隔子字段:

    subfields = bands.split(',')

现在,让我们将该字符串列表转换为布尔值列表,并使用 Python 的内置 any 函数计算整个列表。我们将使用 列表理解:

    if any( [ ('GSM' not in band) for band in subfields ] ):
        _2g_or_not_2g = 'N'

    else:
        _2g_or_not_2g = 'Y'

这个 if 语句大致按照它说的去做:如果任何一个 band 不包含 'GSM',它就会匹配。

还有一些其他方法可以编写此代码。例如,您可以使用 Python all 函数将阴性测试变成阳性测试。这将反转 if 语句的 "sense",并切换武器:

    if all( [ 'GSM' in band for band in subfields ] ):
        _2g_or_not_2g = 'Y'
    else:
        _2g_or_not_2g = 'N'

此外,您可以在列表解析中使用 ... if condition 修饰符将列表过滤为更小的列表。

最后,当然,您可以开始将表达式相互合并 - 将 subfields 替换为实际的拆分表达式等。

需要注意的一点是,在每一行中,每个条带都用逗号分隔。
你可以利用这个。
split() 函数可以为您提供该行的字符串列表,每个字符串包含一个乐队的名称。

现在问题简单多了:如果任何一个波段缺少子字符串 'GSM',那么该行将被取消资格:Return 'N'.
如果该行中的none 个波段不合格(即名称中都包含'GSM),则该行为return 'Y'。

您可以使用 find() 函数查看字符串是否包含给定的子字符串。
例如 'LTE TDD'.find('GSM') returns 值 -1,因为它没有。

请注意,您甚至不需要删除设备 ID - 它可以是包含第一个频段的项目的一部分。保持简单:您只想知道在任何给定行上,所有文本块(以逗号分隔)是否包含子字符串 'GSM' .. 或不包含

def is_GSM(bands):
    for band in bands:
        if (band.find('GSM') = -1:
            return('N')
    return('Y')

for row in reader:
    bands = row.split(',')            
    two_G_only.append(is_GSM(bands))

```

def is_GSM(bands):
    for band in bands:
        if (band.find('GSM') = -1:
            # "GSM" wasn't in the band name
            return('N')

    # we looked at all the bands, and did not find a disqualifier.. 
    # This row must be "GSM' only 2G bands.
    return('Y')

for row in reader:
    # not needed: first strip off the device_id in this row's string.
    # row = row[3:]

    bands = row.split(',') 
    # ie: bands = ['124    GSM 1800', ' GSM 700', ' GSM 1', ' LTE TDD'] 

    # send this list to is_GSM(), and append the result                   
    two_G_only.append(all_are_GSM(bands))

```