세미콜론으로 구분 된 문자열을 Python에서 사전으로 분할


84

다음과 같은 문자열이 있습니다.

"Name1=Value1;Name2=Value2;Name3=Value3"

파이썬에 내장 된 클래스 / 함수가 그 문자열을 받아 사전을 구성하는 것입니까? 마치 내가 이것을 한 것처럼 :

dict = {
    "Name1": "Value1",
    "Name2": "Value2",
    "Name3": "Value3"
}

사용 가능한 모듈을 살펴 봤지만 일치하는 항목을 찾을 수 없습니다.


감사합니다. 관련 코드를 직접 만드는 방법을 알고 있습니다.하지만 그러한 작은 솔루션은 일반적으로 발생하기를 기다리는 광산 분야이기 때문에 (예 : 누군가가 Name1 = 'Value1 = 2';) 등을 작성합니다. 테스트 된 기능.

그럼 내가 할게.


질문이 s = r'Name1='Value=2';Name2=Value2;Name3=Value3;Name4="Va\"lue;\n3"'입력 을 지원해야합니까 (참고 : 인용 된 문자열 내부의 세미콜론, 백 슬래시를 사용하여 인용문이 이스케이프되고, \n이스케이프가 사용되며, 작은 따옴표와 큰 따옴표가 모두 사용됨)?
jfs

이 질문은 6 년이 넘었습니다. 이에 관련된 코드는 오랫동안 교체되었습니다. :) 그리고 따옴표에 대한 지원이 필요하지 않았습니다. 직접 작성하는 대신 미리 빌드 된 함수를 갖고 싶었습니다. 그러나 코드는 오래 전에 사라졌습니다.
Lasse V. Karlsen 2014

답변:


144

내장 기능은 없지만 생성기 이해를 통해 상당히 간단하게 수행 할 수 있습니다.

s= "Name1=Value1;Name2=Value2;Name3=Value3"
dict(item.split("=") for item in s.split(";"))

[편집] 업데이트에서 견적을 처리해야 할 수도 있음을 나타냅니다. 이것은 당신이 찾고있는 정확한 형식이 무엇인지에 따라 일을 복잡하게합니다. csv 모듈이 형식을 포함 할 수 있는지 확인하는 것이 좋습니다. 여기에 예가 있습니다. (CSV는 레코드 시퀀스를 반복하도록 설계 되었기 때문에 API는이 예의 경우 약간 어색합니다. 필요에 맞게) :

>>> s = "Name1='Value=2';Name2=Value2;Name3=Value3"

>>> dict(csv.reader([item], delimiter='=', quotechar="'").next() 
         for item in csv.reader([s], delimiter=';', quotechar="'").next())

{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1=2'}

형식의 정확한 구조에 따라 간단한 파서를 작성해야 할 수도 있습니다.


코드는 인용을 처리하지 않습니다. try : s = "Name1='Value;2';Name2=Value2;Name3=Value3"(참고 : 인용 된 Name1값의 세미콜론 ).
jfs

1
두 번째 예가 왜 AttributeError: '_csv.reader' object has no attribute 'next'나를 위해 던지는 지 모르겠습니다 . 물론 했어요 import csv.
Youngjae

@Brian 문자열이 아닌 정수로 값을 저장하는 방법이 있습니까?
ChasedByDeath

6

이것은 당신이 원하는 것을하는 것과 가깝습니다 :

>>> import urlparse
>>> urlparse.parse_qs("Name1=Value1;Name2=Value2;Name3=Value3")
{'Name2': ['Value2'], 'Name3': ['Value3'], 'Name1': ['Value1']}

2
&또는 %입력에 있으면 중단됩니다 .
jfs

@jfs이지만 문자열에는 둘 중 하나가 포함되어 있지 않습니다.
Vishal Singh

@VishalSingh : StackOverflow의 대부분의 방문자는 Google에서 왔으므로 여기에 대한 답변은 질문을 한 원래 포스터에 대한 것이 아닙니다. "세미콜론으로 구분 된 문자열을 파이썬에서 사전으로"구문 분석하는 방법을 찾으려면 여기에 온 경우 내 문자열에 &또는 %-적어도 해당 문자열에 대한 답변이 작동하지 않는다는 점을 언급 할 가치가 있습니다.
jfs

3
s1 = "Name1=Value1;Name2=Value2;Name3=Value3"

dict(map(lambda x: x.split('='), s1.split(';')))

1

문자열 조인 및 목록 이해로 간단하게 수행 할 수 있습니다.

",".join(["%s=%s" % x for x in d.items()])

>>d = {'a':1, 'b':2}
>>','.join(['%s=%s'%x for x in d.items()])
>>'a=1,b=2'

-2
easytiger $ cat test.out test.py | sed 's/^/    /'
p_easytiger_quoting:1.84563302994
{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1'}
p_brian:2.30507516861
{'Name2': 'Value2', 'Name3': "'Value3'", 'Name1': 'Value1'}
p_kyle:7.22536420822
{'Name2': ['Value2'], 'Name3': ["'Value3'"], 'Name1': ['Value1']}
import timeit
import urlparse

s = "Name1=Value1;Name2=Value2;Name3='Value3'"

def p_easytiger_quoting(s):
    d = {}
    s = s.replace("'", "")
    for x in s.split(';'):
        k, v = x.split('=')
        d[k] = v
    return d


def p_brian(s):
    return dict(item.split("=") for item in s.split(";"))

def p_kyle(s):
    return urlparse.parse_qs(s)



print "p_easytiger_quoting:" + str(timeit.timeit(lambda: p_easytiger_quoting(s)))
print p_easytiger_quoting(s)


print "p_brian:" + str(timeit.timeit(lambda: p_brian(s)))
print p_brian(s)

print "p_kyle:" + str(timeit.timeit(lambda: p_kyle(s)))
print p_kyle(s)

이것은 인용을 처리하지 않기 때문에 질문에 대한 대답이 아닙니다. s = "Name1='Value1=2';Name2=Value2" and csv` (브라이언의 대답에서와 같이)를 시도 하거나 parse_qs(Kyle에서와 같이) 올바르게 가져 오면 ValueError. OP는 구체적으로 "이러한 작은 솔루션은 일반적으로 발생하기를 기다리는 광산 분야"라고 말하며, 이것이 그가 내장 또는 기타 잘 테스트 된 솔루션을 원하는 이유이며 코드를 손상시킬 예제를 제공합니다.
abarnert 2013 년

아, 못 봤어요. 아직도. 반복이 일어나기 전에 메인 문자열의 솔루션을 준비하고 replace 함수를 수천 번 호출하는 것이 모든 솔루션보다 빠릅니다. 나는 업데이트 할 것입니다
easytiger 2013 년

어떻게 준비 할 것인지 잘 모르겠습니다. 그러나 그렇게하더라도 이것은 OP가 간단한 솔루션에서 두려워했던 것과 정확히 같습니다. 앞에 다른 지뢰가없는 것이 확실합니까? OP의 만족을 증명할 수 있습니까?
abarnert 2013 년

좋아, 이제 편집 내용을 봤으니… 첫째, s.replace아무것도하지 않습니다. 무시하는 새 문자열을 반환합니다. 둘째, 맞아도 ( s = s.replace…) 문제가 해결되지는 않지만 그 위에 새로운 문제가 추가됩니다. 내 예 또는 OP에서 시도해보십시오.
abarnert 2013 년

사양에는 그가 그의 질문에서 언급 한 샘플 입력 처리가 명확하게 포함되어 Name='Value1=2';있습니다. 그리고 당신의 코드는 그것을 처리하지 않습니다. 그리고 나는 확실하지 그냥 느린로 될 것입니다 어떤 방법으로 그것을 구문 분석하지 않고 그 살균 것 어떻게 해요 urlparse또는 csv처음이다.
abarnert 2013 년

-2

Value1, Value2가 실제 값에 대한 자리 표시자인 경우 dict()함수를와 함께 사용할 수도 있습니다 eval().

>>> s= "Name1=1;Name2=2;Name3='string'"
>>> print eval('dict('+s.replace(';',',')+')')
{'Name2: 2, 'Name3': 'string', 'Name1': 1}

이것은 dict()함수가 구문을 이해하기 때문 dict(Name1=1, Name2=2,Name3='string')입니다. 문자열의 공백 (예 : 각 세미콜론 뒤)은 무시됩니다. 그러나 문자열 값에는 따옴표가 필요합니다.


감사합니다. upvote string.replace가 잘 작동했습니다. 왜 나눌 수 없었는지 모르겠어요. tc 상자에서 i = textcontrol.GetValue ()를 한 다음 o = i.split ( ';')을 수행했지만 replace와 달리 형식에 대해 불평하는 문자열을 출력하지 않았습니다.
Iancovici 2013-06-13

1
s.replace(';';따옴표 안에 값 이 있으면 기반 솔루션이 중단됩니다 . eval은 악하며이 경우에는 불필요합니다.
jfs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.