从列表中获取值的 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']

如果所有的值(xs)都不一样,需要做大量的检索,可以把字符串转成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])