Sie einen groupby verwenden können, Wörter getrennt werden und __contains__
s = "dylankid: *random words d* senpai: *random words s* dylankid: *random words d* senpai: *random words s*"
from itertools import groupby
d = {"dylankid:": [], "senpai:":[]}
grps = groupby(s.split(" "), d.__contains__)
for k, v in grps:
if k:
d[next(v)].append(" ".join(next(grps)[1]))
print(d)
Ausgabe mit Gruppierung:
{'dylankid:': ['*random words d*', '*random words d*'], 'senpai:': ['*random words s*', '*random words s*']}
Jedes Mal, wenn wir einen bekommen Name in unserem dict verwenden wir diesen Namen mit next(v)
sie erhalten die nächste Gruppierung von Wörtern bis zum nächsten Namen mit str.join
, um wieder zu einer einzigen Zeichenfolge beizutreten.
Wenn Sie keine Worte nach einem Namen zu haben, passiert ist, können Sie leere Listen als Standardwert für den nächsten Aufruf verwenden:
s = "dylankid: *random words d* senpai: *random words s* dylankid: *random words d* senpai: *random words s* senpai:"
from itertools import groupby
d = {"dylankid:": [], "senpai:":[]}
grps = groupby(s.split(" "), d.__contains__)
for k, v in grps:
if k:
d[next(v)].append(" ".join(next(grps,[[], []])[1]))
print(d)
Einige Timings auf größeren Strings:
In [15]: dy, sn = "dylankid:", " senpai:"
In [16]: t = " foo " * 1000
In [17]: s = "".join([dy + t + sn + t for _ in range(1000)])
In [18]: %%timeit
....: d = {"dylankid:": [], "senpai:": []}
....: grps = groupby(s.split(" "), d.__contains__)
....: for k, v in grps:
....: if k:
....: d[next(v)].append(" ".join(next(grps, [[], []])[1]))
....:
1 loop, best of 3: 376 ms per loop
In [19]: %%timeit
....: PATTERN = '''
....: \s* # Any amount of space
....: (dylankid|senpai) # Capture person
....: :\s # Colon and single space
....: (.*?) # Capture everything, non-greedy
....: (?=\sdylankid:|\ssenpai:|$) # Until we find following person or end of string
....: '''
....: res = defaultdict(list)
....: for person, message in re.findall(PATTERN, s, re.VERBOSE):
....: res[person].append(message)
....:
1 loop, best of 3: 753 ms per loop
Both retuurn die gleiche Ausgabe:
In [20]: d = {"dylankid:": [], "senpai:": []}
In [21]: grps = groupby(s.split(" "), d.__contains__)
In [22]: for k, v in grps:
if k:
d[next(v)].append(" ".join(next(grps, [[], []])[1]))
....:
In [23]: PATTERN = '''
....: \s* # Any amount of space
....: (dylankid|senpai) # Capture person
....: :\s # Colon and single space
....: (.*?) # Capture everything, non-greedy
....: (?=\sdylankid:|\ssenpai:|$) # Until we find following person or end of string
....: '''
In [24]: res = defaultdict(list)
In [25]: for person, message in re.findall(PATTERN, s, re.VERBOSE):
....: res[person].append(message)
....:
In [26]: d["dylankid:"] == res["dylankid"]
Out[26]: True
In [27]: d["senpai:"] == res["senpai"]
Out[27]: True
Sie können die [.partition] finden (https://docs.python.org/2/library/stdtypes.html#str.part ition) -Funktion nützlich, da sie Strings nach einem von Ihnen angegebenen Trennzeichen trennen kann. –
Gibt es zufällige Wörter mit ':' in ihnen? –
@PadraicCunningham Ja, es gibt –