【问题标题】:Python: Parse a list of strings into a dictionnaryPython:将字符串列表解析为字典
【发布时间】:2014-10-17 06:09:48
【问题描述】:

这有点复杂。我有一个如下所示的列表:

['19841018 ID1\n', ' Plunging oil... \n', 'cut in the price \n', '\n', '19841018 ID2\n', ' The U.S. dollar...  \n', 'the foreign-exchange markets \n', 'late New York trading \n', '\n']

在我的列表中,'\n' 是一个故事的分隔符。我想做的是从上面的列表中创建一个像这样的字典:

dict = {ID1: [19841018, 'Plunging oil... cut in the price'], ID2: [19841018, 'The U.S. dollar... the foreign-exchange markets']}

您可以看到我的字典中的KEYID,项目是year 和故事的组合。这可行吗?

  • 我的 ID 采用这种格式 J00100394, J00384932。所以他们都以J00开头。

【问题讨论】:

  • 是的,但是您尝试过什么?给我们看一些代码?
  • @avi 你说得很好。我正在与itertools - izip 合作,到目前为止我一团糟。我将很快发布我的暂定代码。我正在努力的是如何结合故事。
  • ID token 有什么限制
  • @MicheleD'Amico 所有 ID 令牌的格式如下所示:J0030484920。所以他们都以J00开头。我现在尝试的是遍历列表中的每个条目,当有 J00 时找到条目并将其存储为键等等。
  • @plug4 我一到办公室就写一个答案。

标签: python parsing


【解决方案1】:

棘手的部分是按任何值拆分您的列表,所以我从here 中获取了这部分。
然后我解析了列表部分以构建res dict

>>> import itertools
>>> def isplit(iterable,splitters):
...     return [list(g) for k,g in itertools.groupby(iterable,lambda x:x in splitters) if not k]
... 
>>> l = ['19841018 ID1\n', ' Plunging oil... \n', 'cut in the price \n', '\n', '19841018 ID2\n', ' The U.S. dollar...  \n', 'the foreign-exchange markets \n', 'late New York trading \n', '\n']
>>> res = {}
>>> for sublist in isplit(l,('\n',)):
...     id_parts = sublist[0].split()
...     story    = ' '.join (sentence.strip() for sentence in sublist[1:])
...     res[id_parts[1].strip()] = [id_parts[0].strip(), story]
... 
>>> res
{'ID2': ['19841018', 'The U.S. dollar... the foreign-exchange markets late New York trading'], 'ID1': ['19841018', 'Plunging oil... cut in the price']}

【讨论】:

  • 哇!谢谢您的帮助。我需要更仔细地研究这段代码。我对itertools 很陌生。如果没有这段代码,我的生活会更加复杂......
  • 事实上.split() 对我来说也是新的。这确实简化了事情。
【解决方案2】:

我编写了一个使用生成器的答案。这个想法是,每次启动一个 id 令牌时,生成器都会返回计算的最后一个键。您可以通过更改check_fun()以及如何混合描述的部分来进行自定义。

def trailing_carriage(s):
    if s.endswith('\n'):
        return s[:-1]
    return s

def check_fun(s):
    """
    :param s:Take a string s
    :return: None if s dosn't match the ID rules. Otherwise return the
    name,value of the token
    """
    if ' ' in s:
        id_candidate,name = s.split(" ",1)
        try:
            return trailing_carriage(name),int(id_candidate)
        except ValueError:
            pass


def parser_list(list, check_id_prefix=check_fun):
    name = None #key dict
    id_candidate = None
    desc = "" #description string
    for token in list:
        check = check_id_prefix(token)
        if check is not None:
            if name is not None:
                """Return the previous coputed entry"""
                yield name,id_val,desc
            name,id_val = check
        else:
            """Append the description"""
            desc += trailing_carriage(token)
    if name is not None:
        """Flush the last entry"""
        yield  name,id_val,desc


>>> list = ['19841018 ID1\n', ' Plunging oil... \n', 'cut in the price \n', '\n', '19841018 ID2\n', ' The U.S. dollar...  \n', 'the foreign-exchange markets \n', 'late New York trading \n', '\n']
>>> print {k:[i,d] for k,i,d in parser_list(list)}
{'ID2': [19841018, ' Plunging oil... cut in the price  The U.S. dollar...  the foreign-exchange markets late New York trading '], 'ID1': [19841018, ' Plunging oil... cut in the price ']}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 2011-12-13
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多