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