从列表中获取值的 Pythonic 方式
Pythonic way of getting a value from a list
编辑:添加了问题的 (b) 部分
我有一个像这样的长字符串:
"a=x b=x c=x..."
a,b,c...始终相同,而 x 不同。我想要的是让我们说 b=x 但前提是 x 匹配特定字符串。
到目前为止,我将字符串传递给列表,然后按空格拆分值,如下所示:
['a=x', 'b=x', 'c=x'...]
a) 仅当 x="something_I_want" 时获得 b=x 的最 pythonic 方法是什么? (已解决)
b) 获得给定 b 的 x 的方法是什么?换句话说,我想得到等于我的已知值 b.
(b) 的解决方案是:
k = "PROTO="
keep = [ele for ele in x.split() if ele.startswith(k)]
print str(keep[0]).split('=')[1]
类似于@Padraic Cunningham 在下面的答案中建议的内容。有没有更有效的方法来做到这一点?
这似乎是您要查找的内容:
>>> s = 'a=1 b=2 c=3 d=4'
>>> parsed = [x.split('=') for x in s.split()]
>>> whatineed = [k for k, v in parsed if v == '2']
>>> whatineed
['b']
如果所有的值(x
s)都不一样,需要做大量的检索,可以把字符串转成value->key
字典:
>>> p = dict(reversed(x.split('=')) for x in s.split())
>>> p
{'1': 'a', '3': 'c', '2': 'b', '4': 'd'}
>>> p['2']
'b'
至于 "pythonic" 位,当您必须以字符串形式处理结构化数据时,将此字符串转换为实际结构(列表, dict) 首先,然后检索您需要的数据。在大多数情况下,使用 string 函数提取 data 既麻烦又不可靠。
一个简单的方法是通过 re
。
import re
x = "a=x b=i_want_this c=x.. b=sdf b=wer."
k="i_want_this"
print re.findall(r"\bb="+re.escape(k)+r"\b",x)
可能不是解决问题的最'pythonic'方法,但我认为这是一个安全的解决方案:)..
def getValueOfString(str, x):
dict = {}
for i in s.split():
item = i.split("=")
if dict.has_key(item[1]):
dict[item[1]].append(item[0])
else:
dict[item[1]] = [item[0]]
return dict[x] if dict.has_key(x) else []
如果您只想根据 x
的值进行过滤,您可以使用 str.endswith
:
的单个列表理解
keep = [ele for ele in s.split() if ele.endswith("=whatever") ]
使用您的测试字符串:
x = "Jun 30 13:07:51 xxxx kernel: 15702368.296557 UFW BLOCK IN=eth1 OUT= MAC=so:me:mac SRC=xx.xx.xx.xx DST=xx.xx.xx.xx LEN=40 TOS=0x00 PREC=0x00 TTL=55 ID=47632 PROTO=TCP SPT=58875 DPT=80 WINDOW=65535 RES=0x00 CK FIN URGP=0"
k = "=TCP"
keep = [ele for ele in x.split() if ele.endswith(k)]
['PROTO=TCP']
一些时间显示仅使用 str.endswith 并且拆分最有效:
In [49]: timeit [ele for ele in x.split() if ele.endswith(k)]
100000 loops, best of 3: 7.81 µs per loop
In [50]: timeit re.findall(r"\b[^= ]*="+re.escape(k)+r"\b",x)
100000 loops, best of 3: 16.5 µs per loop
In [51]: [ele for ele in x.split() if ele.endswith(k)]
Out[51]: ['PROTO=TCP']
In [52]: re.findall(r"\b[^= ]*="+re.escape(k)+r"\b",x)
Out[52]: ['PROTO=TCP']
如果您只想要第一场比赛,或者如果只有一场比赛:
k = "PROTO="
keep = (ele.split("=")[1] for ele in x.split() if ele.startswith(k))
print(next(keep,""))
TCP
或拆分后:
k = "PROTO="
keep = (ele for ele in x.split() if ele.startswith(k))
print(next(keep,"").split("=")[-1])
编辑:添加了问题的 (b) 部分
我有一个像这样的长字符串:
"a=x b=x c=x..."
a,b,c...始终相同,而 x 不同。我想要的是让我们说 b=x 但前提是 x 匹配特定字符串。
到目前为止,我将字符串传递给列表,然后按空格拆分值,如下所示:
['a=x', 'b=x', 'c=x'...]
a) 仅当 x="something_I_want" 时获得 b=x 的最 pythonic 方法是什么? (已解决)
b) 获得给定 b 的 x 的方法是什么?换句话说,我想得到等于我的已知值 b.
(b) 的解决方案是:
k = "PROTO="
keep = [ele for ele in x.split() if ele.startswith(k)]
print str(keep[0]).split('=')[1]
类似于@Padraic Cunningham 在下面的答案中建议的内容。有没有更有效的方法来做到这一点?
这似乎是您要查找的内容:
>>> s = 'a=1 b=2 c=3 d=4'
>>> parsed = [x.split('=') for x in s.split()]
>>> whatineed = [k for k, v in parsed if v == '2']
>>> whatineed
['b']
如果所有的值(x
s)都不一样,需要做大量的检索,可以把字符串转成value->key
字典:
>>> p = dict(reversed(x.split('=')) for x in s.split())
>>> p
{'1': 'a', '3': 'c', '2': 'b', '4': 'd'}
>>> p['2']
'b'
至于 "pythonic" 位,当您必须以字符串形式处理结构化数据时,将此字符串转换为实际结构(列表, dict) 首先,然后检索您需要的数据。在大多数情况下,使用 string 函数提取 data 既麻烦又不可靠。
一个简单的方法是通过 re
。
import re
x = "a=x b=i_want_this c=x.. b=sdf b=wer."
k="i_want_this"
print re.findall(r"\bb="+re.escape(k)+r"\b",x)
可能不是解决问题的最'pythonic'方法,但我认为这是一个安全的解决方案:)..
def getValueOfString(str, x):
dict = {}
for i in s.split():
item = i.split("=")
if dict.has_key(item[1]):
dict[item[1]].append(item[0])
else:
dict[item[1]] = [item[0]]
return dict[x] if dict.has_key(x) else []
如果您只想根据 x
的值进行过滤,您可以使用 str.endswith
:
keep = [ele for ele in s.split() if ele.endswith("=whatever") ]
使用您的测试字符串:
x = "Jun 30 13:07:51 xxxx kernel: 15702368.296557 UFW BLOCK IN=eth1 OUT= MAC=so:me:mac SRC=xx.xx.xx.xx DST=xx.xx.xx.xx LEN=40 TOS=0x00 PREC=0x00 TTL=55 ID=47632 PROTO=TCP SPT=58875 DPT=80 WINDOW=65535 RES=0x00 CK FIN URGP=0"
k = "=TCP"
keep = [ele for ele in x.split() if ele.endswith(k)]
['PROTO=TCP']
一些时间显示仅使用 str.endswith 并且拆分最有效:
In [49]: timeit [ele for ele in x.split() if ele.endswith(k)]
100000 loops, best of 3: 7.81 µs per loop
In [50]: timeit re.findall(r"\b[^= ]*="+re.escape(k)+r"\b",x)
100000 loops, best of 3: 16.5 µs per loop
In [51]: [ele for ele in x.split() if ele.endswith(k)]
Out[51]: ['PROTO=TCP']
In [52]: re.findall(r"\b[^= ]*="+re.escape(k)+r"\b",x)
Out[52]: ['PROTO=TCP']
如果您只想要第一场比赛,或者如果只有一场比赛:
k = "PROTO="
keep = (ele.split("=")[1] for ele in x.split() if ele.startswith(k))
print(next(keep,""))
TCP
或拆分后:
k = "PROTO="
keep = (ele for ele in x.split() if ele.startswith(k))
print(next(keep,"").split("=")[-1])