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

时间:2017-04-19 03:50:52

标签: python python-2.6

我目前正在开发一个项目,我现在的任务是我需要根据Bands列中给出的Band指定设备是否为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

提前感谢您,如果我的问题不可理解,请发表评论。我已经搜索了网站上给出的一些解决方案,但我确信提出的问题不是同样的问题/概念。

2 个答案:

答案 0 :(得分:0)

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

根据我的理解,您的条件是查看第二列中的各个子字段,用逗号分隔,如果每个子字段中包含文本字符串“GSM”,则返回一个值(true)在子字段中,但如果至少有一个子字段不包含该字符串,则返回不同的值(false)。正确?

让我们假设您在reader中拥有自己的csv阅读器,如您的示例所示。 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语句将大致完成它所说的内容:如果任何一个频段未能包含'GSM',它将匹配。

还有其他一些方法可以编写此代码。例如,您可以使用Python all函数将否定测试变为肯定测试。这将颠倒if语句的“意义”,并切换武器:

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

此外,您可以使用列表推导上的... if condition修饰符将列表过滤到较小的列表。

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

答案 1 :(得分:0)

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

现在问题要简单得多:如果任何一个乐队缺少子串'GSM',那么该行将被取消资格:返回'N'。
如果该行中没有一个频段被取消资格,(即名称中都包含“GSM”),则返回该行的“Y”。

您可以使用find()函数查看字符串是否包含给定的子字符串 例如,'LTE TDD'.find('GSM')会返回值-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))

```