【问题标题】:Retrieve a specific substring from each element in a list从列表中的每个元素中检索特定的子字符串
【发布时间】:2018-09-22 08:40:12
【问题描述】:

我被这个困住了几个小时: 我有一个名为 size_col 的系列,包含 887 个元素,我想从大小中检索:S, M, L, XL。我尝试了 2 种不同的方法,列表理解和简单的 if elif 循环,但两种尝试都不起作用。

sizes = ['S', 'M', 'L', 'XL']

tshirt_sizes = []
[tshirt_sizes.append(i) for i in size_col if i in sizes]

第二次尝试:

sizes = []
for i in size_col:
if len(i) < 15:
   sizes.append(i.split(" / ",1)[-1])
else:
   sizes.append(i.split(" - ",1)[-1])

我创建了两个条件,因为在某些情况下大小遵循' - ',而在其他情况下则是'/'。 老实说,我不知道如何处理。

列表示例:

T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "Honey" - L
T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "I do very bad things" - M
T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "Stai nel tuo (mind your business)" - White / S
T-Shirt Donna "Stay Stronz" - White / L
T-Shirt Donna "Stay Stronz" - White / M
T-Shirt Donna "Si dai. Ciao." - S
T-Shirt Donna "Je suis esaurit" - Black / S
T-Shirt Donna "Si dai. Ciao." - S
T-Shirt Donna "Teamo - Tequila" - S / T-Shirt

【问题讨论】:

  • 如果您发布示例,请仅发布文本。我不了解你,但我无法在不运行 tesseract 的情况下从图片中复制粘贴文本,而且工作量太大。
  • @coldspeed 已编辑,抱歉。

标签: python string list substring list-comprehension


【解决方案1】:

您需要在这里regular expressions。预编译正则表达式模式,然后在列表理解中使用 pattern.search

sizes = ['S', 'M', 'L', 'XL']
p = re.compile(r'\b({})\b'.format('|'.join(sizes))) 

tshirt_sizes = [p.search(i).group(0) for i in size_col]

print(tshirt_sizes)
['M', 'L', 'M', 'M', 'M', 'S', 'L', 'M', 'S', 'S', 'S', 'S']

为了增加安全性,您可能需要一个循环 - 列表推导式不适合错误处理:

tshirt_sizes = []
for i in size_col:
    try:
        tshirt_sizes.append(p.search(i).group(0))
    except AttributeError:
        tshirt_sizes.append(None)

真正在这里使用正则表达式的唯一原因是适当地处理数据中的最后一行。一般来说,如果可以的话,除非可以避免,否则您应该更喜欢使用字符串操作(即str.split),它们比基于正则表达式的模式匹配和提取要快得多且可读性强。

【讨论】:

    【解决方案2】:

    你可以这样做:

    available_sizes = ["S", "M", "L", "XL"]
    sizes = []
    
    for i in size_col:
        for w in i.split():
            if w in available_sizes:
                sizes.append(w)
    

    如果文本多次包含 available_sizes 中的单词,例如T-Shirt Donna "La S è la più bella consonante" - M,这将不起作用,因为它会将 S 和 M 添加到列表中。


    原始答案,在 OP 指定大小并不总是最后一个字之前。

    几乎。只需将字符串拆分为单词并取最后一个。

    sizes = []
    for i in size_col:
        sizes.append(i.split()[-1])
    

    【讨论】:

    • 抱歉,刚刚看到对文件的编辑。显然,大小并不总是硬道理。很快就会编辑。
    • 那行不通,在某些情况下,大小不是最后一个元素,而且这对 'XL' 不起作用
    • 这适用于 XL,因为它需要最后一个字。但如果大小不是硬道理,那就不行了。
    • 我更新了答案。新实现等同于公认的实现,但在我的机器上稍快一些:14.6 µs ± 214 ns 对比 22.7 µs ± 1.09 µs,根据魔术命令 %timeit 的说法。
    【解决方案3】:

    这个问题有两个方面,1)循环遍历元素的最佳方法和2)拆分字符串的正确方法。

    在一般情况下,列表推导式可能是解决此类问题的正确方法,但您已经正确识别出正确拆分字符串是很棘手的。

    对于这种类型的问题regular expressions 非常强大,并且(与之前的答案相比可能会使问题复杂化)你可以使用类似的东西:

    import re
    pattern = re.compile(r'[-/] (A-Z)$') # select any uppercase letters after either - or / and a space and before the end of the line (marked by $)
    
    sizes = [pattern.search(item).group(1) for item in size_col] # group 1 selects the set of characters in the first set of parentheses (the letters)
    

    已编辑:刚刚看到帖子的编辑说明该项目并不总是在最后,COLDSPEED 的答案重复了这个......

    【讨论】:

      猜你喜欢
      • 2020-01-09
      • 2012-01-30
      • 1970-01-01
      • 2018-09-08
      • 2023-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      相关资源
      最近更新 更多