【问题标题】:How to extract the values from dictionary with condition如何从有条件的字典中提取值
【发布时间】:2020-01-28 14:01:40
【问题描述】:

我需要使用正则表达式从字典列表中提取手机号码。

只需要从d[num]中提取

字典:

d = [{'name': 'a', 'num': '9134567890','num2':'912311111'},
    {'name': 'd', 'num': '9134567890','num2':'5151'},
    {'name': 'b', 'num': '0134567890','num2':'51'},
    {'name': 'c', 'num': '9034567890','num2':'12'},
    {'name': 'm', 'num': '9034590','num2':'13'}
    ]
  1. 电话号码是每个字典的键 "num" 的值。
  2. 所有电话号码必须包含 10 位数字。
  3. 如果电话号码以91开头,则为'local'
  4. 如果电话号码以01开头,则为'global'
  5. 如果电话号码以其他任何开头,则为'others'

伪代码:

s = {'locals':[], 'global':[], 'others':[]}
for i in d:
    for k,v in i.items():
        #if num starts with 91:
           #append locals
        #elif num starts with 01:
           #append to globals
        #else:
            #append to others

伪代码

for i in my_dict_1:
    print ([ v for k,v in i.items() if str(v).startswith('91') if i['num']])

我的预期输出:

{'locals':[a,d], 'global':['b'], 'others':['d']}

由于问题被搁置,我已经解决了问题

s = {'locals':[], 'global':[],'others':[]}
for i in d:
    if i['num'].startswith('91'):
        s['locals'].append(i['num'])
    elif i['num'].startswith('01'):
        s['global'].append(i['num'])
    else:
        s['others'].append(i['num'])
s

出来

{'global': ['0134567890'],
 'locals': ['9134567890', '9134567890'],
 'others': ['9034567890', '9034590']}

【问题讨论】:

  • 我不清楚它为什么被搁置。虽然措辞不好,可能是由于语言限制(原帖已被编辑),但我相信它确实有足够的细节来提供足够的答案。它并没有问多个问题。相反,它对一个问题提出了多个条件。
  • 你快到了。只需删除第二个for 循环并将第一个if 语句替换为if i[num].startswith('91'): s['locals'].append(i[num]) 其他将类似。

标签: python regex list dictionary


【解决方案1】:

您可以使用带有交替的正则表达式和 defaultdict,如下所示:

from collections import defaultdict
import re

d = [
    {'name': 'a', 'num': '9134567890','num2':'912311111'},
    {'name': 'd', 'num': '9134567890','num2':'5151'},
    {'name': 'b', 'num': '0134567890','num2':'51'},
    {'name': 'c', 'num': '9034567890','num2':'12'},
    {'name': 'm', 'num': '9034590','num2':'13'}
]

# regular expression
rx = re.compile(r'^(?=\d{10}$)(?P<local>91.+)|(?P<global>01.+)|(?P<others>.+)')

# output dict
output = defaultdict(list)

# list comprehension
_ = [output[key].append(m[key])
     for item in d
     for m in [rx.search(item["num"])] if m
     for key in m.groupdict() if m[key]]

print(output)

这会产生

defaultdict(<class 'list'>, {'local': ['9134567890', '9134567890'], 'global': ['0134567890'], 'others': ['9034567890', '9034590']})


正则表达式确保正好有 10 位数字(这就是正向预测所做的),然后将不同的匹配项放入相应的组中。之后我们检查哪个 dict 已被填写在一个大的理解中。

【讨论】:

    【解决方案2】:

    @简

    我还是 Python 中的正则表达式的新手。不应该在“其他”中排除数字“9034590”,因为它不包含十位数字吗?您将如何修复 rx 中的 ^(?=\d{10}$) 部分?

    我将该行更改为(诚然不是最好的解决方法,但它仍然有效)

    rx = re.compile(r'(?P<local>91\d{8})|(?P<global>01\d{8})|(?P<others>\d{10})')
    

    这会产生

    defaultdict(<class 'list'>, {'local': ['9134567890', '9134567890'], 'global': ['0134567890'], 'others': ['9034567890']})
    

    按照海报的要求。

    编辑: 我想通了(更好的解决方法),@Jan 你错过了三个 or 表达式的括号。

    rx = re.compile(r'^(?=\d{10}$)((?P<local>91\d+)|(?P<global>01\d+)|(?P<others>\d+))')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 2013-07-09
      • 2018-09-19
      • 1970-01-01
      相关资源
      最近更新 更多