Как преобразовать плоский список в словарь на Python?

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть плоский список, содержащий информацию о нескольких переменных, и мне нужно преобразовать его в словарь. Например, ‘a’, ‘b’, ‘c’ являются именами переменных и должны быть ключами в словаре. Список может быть разделен на ‘_’ и ‘:’.

 list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']
  

Желаемый результат будет:

 dict_x = {'a':[1,2,4],'b':[45,24,78],'c':['abc','def','xxx']}
  

Я не уверен, как выполнить цикл, чтобы получить ключи для словаря, поскольку он одинаков для всех элементов в списке.

Комментарии:

1. это большая работа! что вы пробовали до сих пор?

2. просто для подтверждения, вы хотите список строк в виде dict с ключами и значениями в виде списка? Кроме того, значения должны быть целыми числами, где это возможно, и строкой, где это не так? Если да, пожалуйста, проверьте мое решение и решает ли оно то, что вам нужно.

Ответ №1:

 lst = [y.split(":") for x in [x.split("_") for x in list_x] for y in x]
d = {x:[] for x in set([x[0] for x in lst])}
for k, v in lst:
    d[k].append(v)
# Out[40]: {'a': ['1', '2', '4'], 'c': ['abc', 'def', 'xxx'], 'b': ['45', '24', '78']}
  

Комментарии:

1. @ponderwonder если это было полезно, можете ли вы выбрать ответ в качестве принятого ответа, чтобы помочь будущим читателям?

Ответ №2:

Попробуйте этот метод (объяснение встроено в комментарии к коду) —

 #Function to turn a list of tuples into a dict after converting integers and keeping string types.
def convert(tup):
    di = {}
    for a, b in tup:
        if b.isdecimal(): #convert to int if possible
            b = int(b)
        di.setdefault(a, []).append(b) 
    return di 

#convert the input into a list of tuples
k = [tuple(j.split(':')) for i in list_x for j in i.split('_')]

#convert list of tuples into dict
convert(k)
  
 {'a': [1, 2, 4], 'b': [45, 24, 78], 'c': ['abc', 'def', 'xxx']}
  

Ответ №3:

 list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']

result_dict = {}

for list_element in list_x:
    key_val_pair = list_element.split('_')

    for key_val in key_val_pair:
        key, val = key_val.split(':')

        if key not in result_dict:
            result_dict[key] = []

        result_dict[key].append(val)

print(result_dict)            
  

Ответ №4:

Вам нужно убедиться, что ваш словарь является словарем типа string: list вот почему я проверяю, содержит ли словарь ключ, и если это так, то я нажимаю элемент, а если нет, то добавляю новый ключ со списком, содержащим только значение.

 list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']
print(list_x)

dic_x = dict()

for x in list_x:
    keyValueList = x.split('_')
    for keyValue in keyValueList:
        split = keyValue.split(':')
        key = split[0]
        value = split[1]
        if key in dic_x:
            dic_x[key].append(value)
        else:
            dic_x.update({key: [value]})

print(dic_x)
  

Ответ №5:

Предполагая, что строки в вашем list_x всегда имеют тот же формат, что и: a:integer_b:integer_c:string , вы можете сделать это:

 dict_x = {'a':[],'b':[],'c':[]}
for s in list_x:
    sl = s.split('_')
    dict_x['a'].append(int(sl[0][2:]))
    dict_x['b'].append(int(sl[1][2:]))
    dict_x['c'].append(sl[2][2:])
  

Ответ №6:

Возможно, это может решить вашу проблему простым способом, не будучи слишком подробным и компактным. Он универсален, поэтому вы можете добавить столько идентификаторов, сколько хотите, но, как вы можете видеть, их формат должен быть одинаковым

 list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']
dict_x ={}

for val in list_x:
  elements = val.split('_')
  for el in elements:
    key, value = el.split(':')[0], el.split(':')[1]
    if dict_x.get(key) is None:  #If the key it's founded for the first time
      dict_x[key] = [value]
    else:                        #If I've already founded the key the data is being appended
      dict_x[key].append(value)
print(dict_x)
  

Как вы можете видеть, ядро — это if, которое проверяет, не существует ли ключ, основанный на, в этом случае создайте новый массив, содержащий первое значение, основанное; в противном случае добавьте значение к фактическому массиву.

Комментарии:

1. Если мой ответ решил вашу проблему, пожалуйста, проверьте его как решение, чтобы любой пользователь мог использовать его в будущем. Спасибо!

Ответ №7:

Сначала разделите каждую строку на основе _ разделителя as, а затем разделите ее на основе : разделителя as и добавьте каждый элемент в dict

 >>> list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']
>>> 
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for s in list_x:
...     for kv in s.split('_'):
...         k,v = kv.split(':')
...         d[k].append(int(v) if v.isdigit() else v)
... 
>>> dict(d)
{'a': [1, 2, 4], 'b': [45, 24, 78], 'c': ['abc', 'def', 'xxx']}
  

Ответ №8:

Сначала давайте разделим строку на ‘:’, а затем на ‘_’

 list_x = ['a:1_b:45_c:abc','a:2_b:24_c:def','a:4_b:78_c:xxx']

def parse(s):
    return [t.split(":") for t in s.split("_")]

parsed_to_lists = [parse(st) for st in list_x]  

  

Теперь у нас есть

 [[['a', '1'], ['b', '45'], ['c', 'abc']], [['a', '2'], ['b', '24'], ['c', 'def']], [['a', '4'], ['b', '78'], ['c', 'xxx']]]
  

мы можем сгладить это с помощью

 flat_list = [item for sublist in parsed_to_lists for item in sublist]

flat_list
  

Который возвращает

 [['a', '1'], ['b', '45'], ['c', 'abc'], ['a', '2'], ['b', '24'], ['c', 'def'], ['a', '4'], ['b', '78'], ['c', 'xxx']]
  

Мы хотим получить результат в виде словаря списков, поэтому давайте создадим пустой

 from collections import defaultdict

res = defaultdict(list)
  

и заполните его

 for k,v in flat_list:
    res[k].append(v)

res

defaultdict(<class 'list'>, {'a': ['1', '2', '4'], 'b': ['45', '24', '78'], 'c': ['abc', 'def', 'xxx']})