পাইথনের একটি অভিধানে একটি সেমিকোলন-বিভাজিত স্ট্রিং বিভক্ত করা


86

আমার কাছে একটি স্ট্রিং রয়েছে যা দেখতে এটির মতো দেখাচ্ছে:

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

পাইথনে একটি অন্তর্নির্মিত শ্রেণি / ক্রিয়াকলাপ রয়েছে যা সেই স্ট্রিংটি নেবে এবং একটি অভিধান তৈরি করবে, যেমন আমি এটি করেছিলাম:

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

আমি উপলব্ধ মডিউলগুলি দেখেছি কিন্তু এর সাথে মেলে এমন কোনও কিছুই খুঁজে পাচ্ছি না।


ধন্যবাদ, আমি কীভাবে প্রাসঙ্গিক কোডটি বানাতে পারি তা জানি না, তবে এই জাতীয় ক্ষুদ্র সমাধানগুলি সাধারণত আমার ক্ষেত্রগুলি হওয়ার অপেক্ষায় থাকে (যেমন: কেউ লিখেছেন: নাম 1 = 'মান 1 = 2';) ইত্যাদি তবে আমি সাধারণত কিছু প্রাক-পছন্দ পছন্দ করি- পরীক্ষিত ফাংশন।

আমি নিজেই তখন করবো।


আপনার প্রশ্নের কি s = r'Name1='Value=2';Name2=Value2;Name3=Value3;Name4="Va\"lue;\n3"'ইনপুট সমর্থন করা দরকার (দ্রষ্টব্য: একটি উদ্ধৃত স্ট্রিংয়ের ভিতরে একটি সেমিকোলন, ব্যাকস্ল্যাশ ব্যবহার করে একটি উদ্ধৃতি পালানো হয়েছে, পালানো ব্যবহার \nকরা হয়, একক এবং ডাবল উভয় উদ্ধৃতি ব্যবহৃত হয়)?
jfs

আমার এই প্রশ্নটি 6 বছরেরও বেশি পুরনো, এতে জড়িত কোডটি দীর্ঘকাল থেকে প্রতিস্থাপন করা হয়েছে :) এবং না, এর উদ্ধৃতিগুলির জন্য সমর্থন প্রয়োজন হয়নি। আমি নিজে কিছু লেখার পরিবর্তে একটি প্রাক-বিল্ট ফাংশন করতে চাই। তবে কোডটি অনেক আগেই চলে গেছে।
ল্যাসে ভি কার্লসেন

উত্তর:


145

এখানে কোনও বিল্টিন নেই, তবে আপনি জেনারেটর বোঝার সাথে এটি কেবল মোটামুটিভাবে সম্পাদন করতে পারেন:

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

[সম্পাদনা] আপনার আপডেট থেকে আপনাকে নির্দেশ করে যে আপনার উদ্ধৃতি হ্যান্ডেল করতে হতে পারে। আপনি যা সঠিক ফর্ম্যাটটি খুঁজছেন তা কিসের উপর নির্ভর করে (কোন উদ্ধৃতিচর্চাগুলি গ্রহণ করা হয়, কী পালানোর চরগুলি ইত্যাদি) এর উপর নির্ভর করে এটি জিনিসগুলিকে জটিল করে তোলে। এটি আপনার ফর্ম্যাটটি কভার করতে পারে কিনা তা দেখতে আপনি সিএসভি মডিউলটি দেখতে চাইতে পারেন। এখানে একটি উদাহরণ দেওয়া আছে: (নোট করুন যে এপিআই এই উদাহরণটির জন্য কিছুটা ক্লানকি, যেমন সিএসভি রেকর্ডের অনুক্রমের মাধ্যমে পুনরাবৃত্তি করার জন্য ডিজাইন করা হয়েছে, অতএব আমি প্রথম লাইনের দিকে নজর দেওয়ার জন্য .Nxt () কলগুলি সামঞ্জস্য করছি to আপনার প্রয়োজন অনুসারে):

>>> 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'}

আপনার ফর্ম্যাটের সঠিক কাঠামোর উপর নির্ভর করে আপনাকে নিজের নিজস্ব পার্সার লিখতে হবে।


কোড উদ্ধৃতি হ্যান্ডেল করে না, চেষ্টা করুন: s = "Name1='Value;2';Name2=Value2;Name3=Value3"(দ্রষ্টব্য: উদ্ধৃত মানটিতে অর্ধিকোলন Name1)
jfs

4
দ্বিতীয় উদাহরণটি কেন AttributeError: '_csv.reader' object has no attribute 'next'আমার জন্য ছুড়ে ফেলেছে তা আমার কোনও ধারণা নেই । অবশ্যই করেছি import csv
ইয়াংজায়ে

@ ব্রায়ান স্ট্রিংয়ের চেয়ে মানগুলি পূর্ণসংখ্যা হিসাবে সংরক্ষণ করার কোনও উপায় আছে কি?
তাড়াতাড়ি বাইডিডথ

কীভাবে এর বিপরীত কাজটি করতে পারেন @ ব্রেন
জামিল নইদা

6

এটি আপনি যা চেয়েছিলেন তা করার কাছাকাছি আসে:

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

4
ইনপুট থাকলে &বা এটি ভেঙে %যায়।
jfs

@jfs তবে স্ট্রিংটিতে সেগুলির একটিও নেই।
বিশাল সিং

@ বিষালসিংহ: স্ট্যাকওভারফ্লোতে বেশিরভাগ দর্শক গুগল থেকে এসেছেন এবং সুতরাং এখানে উত্তরগুলি কেবল সেই মূল পোস্টারকেই নয় যারা প্রশ্ন জিজ্ঞাসা করেছিল। আমি যদি এখানে পাইথন-এর একটি "অর্ধবৃত্ত-বিভাজনযুক্ত স্ট্রিংটিকে একটি অভিধানে কীভাবে পার্স করতে চাইছি" তা হলে আমার স্ট্রিংগুলিতে থাকতে পারে &বা %- খুব কমপক্ষে, এটি উল্লেখ করার মতো যে উত্তরটি এই ধরনের স্ট্রিংগুলির জন্য কাজ করে না।
jfs


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 সিএসভি চেষ্টা করুন (ব্রায়ানের গৃহীত উত্তরের মতো) বা parse_qs( কাইলির মতো ) এটি সঠিক হবে, যখন আপনার একটি উত্থাপন করবে ValueError। ওপি বিশেষত বলেছে যে "এই জাতীয় ক্ষুদ্র সমাধানগুলি সাধারণত আমার ক্ষেত্রগুলি হওয়ার অপেক্ষায় থাকে", এ কারণেই তিনি একটি অন্তর্নির্মিত বা অন্য ভালভাবে পরীক্ষা করা সমাধান চান এবং তিনি একটি উদাহরণ দিয়েছেন যা আপনার কোডটি ভঙ্গ করবে।
05 এ অবার্নার্ট

আহ আমি তা দেখিনি। এখনও পুনরাবৃত্তি সঞ্চালনের আগে এবং প্রতিস্থাপনের কাজটি কয়েক হাজার বার স্মরণ করে নেওয়ার আগে মূল স্ট্রিংগুলিতে প্রস্তুত করা আপনার সমস্ত সমাধানের চেয়ে দ্রুততর হবে। আমি আপডেট করব
ইজিটিজেগার ২ger

আপনি কীভাবে এটি প্রস্তুতি নিতে চলেছেন তা আমি নিশ্চিত নই। তবে আপনি তা করলেও এটি সাধারণ সমাধানে ওপি ভয় পেয়েছিল বলে মনে হয় like আপনি কি নিশ্চিত যে সামনে আর কোনও খনি নেই? আপনি কি ওপির সন্তুষ্টি প্রমাণ করতে পারবেন?
অবতরণ ২৮

ঠিক আছে, এখন আমি আপনার সম্পাদনাটি দেখেছি ... প্রথমে, s.replaceকিছু করা যায় না; এটি কেবলমাত্র একটি নতুন স্ট্রিং দেয় যা আপনি উপেক্ষা করেন। দ্বিতীয়ত, এমনকি যদি আপনি এটি সঠিক ( s = s.replace…) পেয়ে থাকেন তবে এটি সমস্যার সমাধান করে না, এটি কেবল এটির উপরে একটি নতুন যুক্ত করে। আমার উদাহরণ বা ওপি এর দুটিতে এটি ব্যবহার করে দেখুন।
abarnert

স্পেসিফিকেশন পরিষ্কারভাবে, নমুনা ইনপুট তিনি তার প্রশ্নে আপনাকে উল্লেখ করেছে হ্যান্ডলিং অন্তর্ভুক্ত Name='Value1=2';। এবং আপনার কোড এটি পরিচালনা করে না। এবং আমি নিশ্চিত নই যে আপনি কীভাবে স্যানিটাইজ করবেন তা কোনও উপায়ে পার্সিং না করে যা প্রথম স্থানের মতো urlparseবা ধীরে ধীরে হবে csv
0:34 এ abarnert

-2

যদি আপনার মান 1, মান 2 প্রকৃত মানগুলির জন্য কেবল স্থানধারক হয় তবে dict()আপনি মিশ্রণে ফাংশনটিও ব্যবহার করতে পারেন eval()

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

এই beacuse dict()ফাংশন সিনট্যাক্স বুঝতে dict(Name1=1, Name2=2,Name3='string')। স্ট্রিংয়ের ফাঁকা স্থান (যেমন প্রতিটি সেমিকোলনের পরে) উপেক্ষা করা হয়। তবে নং স্ট্রিংয়ের মানগুলি উদ্ধৃত করা দরকার।


ধন্যবাদ, আপভোট স্ট্রিং.রেপ্লেস ভালভাবে কাজ করেছে। জানি না কেন আমি বিচ্ছেদ করতে পারিনি। আমি টিসি বাক্সে i = টেক্সটকন্ট্রোল.গেটভ্যালু () করেছি, তারপরে o = i.split (';') তবে প্রতিস্থাপনের পরিবর্তে ফর্ম্যাট সম্পর্কে একটি স্ট্রিং আউটপুট দেয়নি।
ইয়ানকোভিচি

4
s.replace(';'ভিত্তিযুক্ত সমাধানটি যদি ;একটি উদ্ধৃত মানের ভিতরে থাকে তবে ব্রেক হয়ে যায় । eval মন্দ এবং এটি এক্ষেত্রে অপ্রয়োজনীয়।
jfs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.