从列表中获取值的Pythonic方法

时间:2015-03-12 10:06:25

标签: python string list parsing split

编辑:添加了问题的(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在答案中建议的内容。有没有更有效的方法来做到这一点?

4 个答案:

答案 0 :(得分:2)

这似乎是您正在寻找的:

>>> 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"当你必须以字符串形式处理结构化数据时,它首先将这个字符串转换为实际结构(list,dict),并且更清洁(因此更多pythonic")然后检索您需要的数据。在大多数情况下,使用 string 函数提取数据很麻烦且不可靠。

答案 1 :(得分:2)

一种简单的方法是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)

答案 2 :(得分:0)

可能不是最多的' 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 []

答案 3 :(得分:0)

如果您只想根据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和split是最有效的:

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])