Значения в словаре python преобразуются в двойные кавычки, а не в одинарные кавычки

У меня есть словарь со следующими значениями: -

test_dict = {'a': ['a1', 'a2'], 'b': ['1.1.1.1:1111', '2.2.2.2:2222', '3.3.3.3:3333,4.4.4.4:4444', '5.5.5.5:5555']}

Мне нужно заменить запятую (,) между 3.3.3.3:3333 и 4.4.4.4:4444 на (',), которая (запятая в одинарной кавычке), как и у других.

Я попробовал код ниже, но вывод идет с двойными кавычками (")

val = ','
valnew = '\', \''  # using escape characters - all are single quotes
for k, v in test_dict.items():
    for i, s in enumerate(v):
        if val in s:
           v[i] = s.replace(val, valnew)

print(test_dict)

Выход:

{'a': ['a1', 'a2'], 'b': ['1.1.1.1:1111', '2.2.2.2:2222', "3.3.3.3:3333', '4.4.4.4:4444", '5.5.5.5:5555']}

Ожидаемый результат:

{'a': ['a1', 'a2'], 'b': ['1.1.1.1:1111', '2.2.2.2:2222', '3.3.3.3:3333', '4.4.4.4:4444', '5.5.5.5:5555']}

Пожалуйста, предложите.


person Pynewbie    schedule 13.06.2020    source источник
comment
'3.3.3.3:3333,4.4.4.4:4444' — это одна строка. Возможно, у вас есть ошибка в том, что изначально составило список? Может ли какой-либо из этих списков иметь проблему или это всегда индекс списка 2?   -  person tdelaney    schedule 13.06.2020
comment
Спасибо! @tdelaney. В словаре нет ошибок. Источник, из которого мы получаем эту комбинацию, совпадает с тем, что я разместил в своем вопросе.   -  person Pynewbie    schedule 13.06.2020


Ответы (4)


Попробуйте что-то вроде этого:

test_dict["b"] = ",".join(test_dict["b"]).split(",")

Обновлено:

import re

# do this once for the entire list
do_joinsplit_regex = re.compile(
    r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,4}"
)

for d in sample_list:
    for k,v in d.items():
        if not isinstance(v, list) or len(v) < 1:
            continue
        d[k] = ",".join(v).split(",")

person Community    schedule 13.06.2020
comment
Почему вы присоединяетесь только для того, чтобы снова расстаться? - person wjandrea; 13.06.2020
comment
Потому что проблема в том, что одного элемента в этом списке на самом деле должно быть два, и быстрый способ справиться с этим — просто объединить или «присоединить» его к другим элементам списка. Если вы разделите эту строку запятой, у вас будут все записи. Что касается проблемы с кавычками, прошу прощения. Я использую мобильное приложение, и оно не так надежно, как клавиатура моего компьютера. Не стесняйтесь редактировать его! - person ; 13.06.2020
comment
Хорошо, я исправил цитаты для вас. Пока я был там, я заметил, что понимание было излишним, поэтому я тоже удалил его. Теперь гораздо короче! :) - person wjandrea; 13.06.2020
comment
Благодарю вас! Кроме того, я должен был сказать, что клавиатура моего мобильного устройства не так надежна, как клавиатура моего компьютера. - person ; 13.06.2020
comment
Спасибо will_f и wjandrea. Это выглядит коротко и мило :). Работает как шарм. - person Pynewbie; 13.06.2020
comment
Спасибо! У меня был дополнительный вопрос. Для одного словаря работает нормально, но теперь у меня есть несколько словарей, и они хранятся в списке. Например. sample_list=[{'хост': ['a1', 'a2'], 'ip': ['1.1.1.1:1111', '2.2.2.2:2222', '3.3.3.3:3333,4.4.4.4: 4444', '5.5.5.5:5555']}, {'хост': ['c1', 'c2'], 'ip': ['1.1.1.1:1111', '2.2.2.2:2222', ' 3.3.3.3:3333,4.4.4.4:4444', '5.5.5.5:5555']}]. Я использую функцию обновления с помощью цикла, и вот код. Это не работает. для d в sample_list: j.update((v, (,.join(d[ip]).split(,))) для k,v в d.items(), если v ==ip). Не могли бы вы помочь предложить. Он не выдает никакой ошибки - person Pynewbie; 15.06.2020
comment
Я (медленно) сделал обновление, которое работает достаточно хорошо. Обязательно найдите лучшее регулярное выражение для пар ip:port (то есть такое, которое может обрабатывать ipv4 и ipv6). - person ; 15.06.2020
comment
Это круто! :) Спасибо will_f. Затем мне пришлось скопировать значения в текстовый файл в виде столбцов. Например. для каждого значения в 1-м словаре мне пришлось скопировать все соответствующие значения из 2-го словаря в виде столбца в новых строках один за другим. Я смог добиться этого, выполнив следующие действия: with open('test.txt', 'w') as f: for d in sample_list: for i in product(d['host'], d['ip'] ): f.write('{} {}\n'.format(*i)). Для этого я импортировал продукт из itertools. Я новичок в этом и хотел бы еще раз поблагодарить вас :) - person Pynewbie; 15.06.2020

print отображает представление dict, как если бы был вызван print(repr(test_dict)).

[repr возвращает] строку, содержащую печатное представление объекта. Для многих типов эта функция пытается вернуть строку, которая дала бы объект с тем же значением при передаче в eval() ..

Поскольку значение представляет собой строку, содержащую ', вместо нее используется " во время представления строки. Пример:

print(repr("helloworld"))   # -> 'helloworld'
print(repr("hello'world"))  # -> "hello'world"

Обычно это представление следует использовать только в диагностических целях. Если необходимо написать этот специальный формат, необходимо пройтись по словарю и распечатать значения явно «в соответствии с требованиями».

Если вам нужен надежный вывод/кодирование с четко определенными правилами сериализации, используйте общий формат, такой как JSON, XML, YAML и т. д.

person user2864740    schedule 13.06.2020

Вы путаете данные с представлением. Одинарные кавычки, пробел и запятая ', ' являются частью представления строк внутри списка, а не самой строки.

На самом деле вы пытаетесь разбить строку на запятую, например.

>>> '3,4'.split(',')
['3', '4']

Вы можете сделать это в списке, разбивая и сглаживая, например:

[s1 for s0 in v for s1 in s0.split(',')]

So:

>>> b = ['1', '2', '3,4', '5']  # Using simpler data for example
>>> b = [s1 for s0 in b for s1 in s0.split(',')]
>>> print(b)
['1', '2', '3', '4', '5']
person wjandrea    schedule 13.06.2020
comment
Спасибо за объяснение. Это действительно полезно. Получил разницу между данными и представлением. - person Pynewbie; 13.06.2020

'3.3.3.3:3333,4.4.4.4:4444' - это одна строка, а внешние кавычки - это просто способ python показать это. То же самое для "3.3.3.3:3333', '4.4.4.4:4444" - это одна строка. Внешние двойные кавычки - это просто способ python показать вам строку. Внутренние одинарные кавычки и запятая — это буквально те символы в строке.

Ваша проблема заключается в том, что некоторые значения в списке были объединены. Вероятно, проблема в том, кто написал этот список в первую очередь. Мы можем исправить это, разделив строки и расширив список. Элементы списка, в которых нет встроенных запятых, разделены на один список элементов, поэтому расширяются в наш новый список как один элемент. Без изменений. Но элементы с запятой разбиваются на список из 2 элементов и расширяют новый список на 2.

test_dict = {'a': ['a1', 'a2'], 'b': ['1.1.1.1:1111', '2.2.2.2:2222', '3.3.3.3:3333,4.4.4.4:4444', '5.5.5.5:5555']}

def list_expander(alist):
    """Return list where values with a comma are expanded"""
    new_list = []
    for value in alist:
        new_list.extend(value.split(","))
    return new_list

new_dict = {key:list_expander(val) for key, val in test_dict.items()}
print(new_dict)

Результат

{'a': ['a1', 'a2'], 'b': ['1.1.1.1:1111', '2.2.2.2:2222', '3.3.3.3:3333', '4.4.4.4:4444', '5.5.5.5:5555']}
person tdelaney    schedule 13.06.2020
comment
Спасибо еще раз. Это действительно полезно. Спасибо и за объяснение. - person Pynewbie; 13.06.2020