পৃথক ভেরিয়েবলের অভিধান তৈরি করার সহজ উপায়?


220

আমি একটি স্ট্রিং হিসাবে একটি ভেরিয়েবলের নাম পেতে সক্ষম হতে চাই তবে পাইথনের এতো অন্তর্নির্ধারণের ক্ষমতা আছে কিনা তা আমি জানি না। কিছুটা এইরকম:

>>> print(my_var.__name__)
'my_var'

আমি এটি করতে চাই কারণ আমার কাছে প্রচুর ভেরিয়েবল রয়েছে যা আমি এর মতো একটি অভিধানে রূপান্তর করতে চাই:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

তবে আমি এর চেয়ে আরও বেশি কিছু স্বয়ংক্রিয় চাই।

পাইথন আছে locals()এবং vars()তাই আমি অনুমান করি একটি উপায় আছে।


31
যেহেতু লোকেদের জিজ্ঞাসা করা হয়েছে সে সম্পর্কে আমি বিভ্রান্ত বলে মনে হচ্ছে আমি এটি এখানে পুনরায় ফিরিয়ে দেব কারণ এটি একটি আকর্ষণীয় প্রশ্ন। একটি অ্যারে দেওয়া হয়েছে [ফু, বার, বাজ] আপনি dictionary 'foo': foo, 'বার': বার, 'বাজ': বাজ like এর মতো একটি অভিধান চাইছেন এবং অ্যারেতে কী ভেরিয়েবল রয়েছে তা আপনি জানেন না। সুতরাং প্রশ্নকর্তা আপনাকে জিজ্ঞাসা করছেন যে কীভাবে আপনি পাইথনের স্ট্রিং হিসাবে কোনও ভেরিয়েবলের নাম পান। এখন আশা করা যায় যে লোকেরা অজস্র ক্ষেত্রে কেন এটি সত্যিই ভাল ধারণা নয় এমন কয়েকটি জায়গাগুলি সন্ধান করার জন্য ভয়ঙ্কর প্রতিক্রিয়ার মধ্য দিয়ে নেভিগেট করতে পারে।
জেসি শার্লক


2
কৌশলটির জন্য একটি ব্যবহার স্ট্রিং ফর্ম্যাটিং কলগুলি প্রবাহিত করতে হবে: '{var} {foo} {বার}' format 'var': var) বর্ণিত হিসাবে।
গর্ডন বিন

4
আমি মনে করি এটি আসলে একটি খারাপ প্রশ্ন কারণ নামগুলিকে বস্তুর সাথে ম্যাপ করা হয়, আপনার একই জিনিসটির দিকে ইশারা করে একাধিক নাম থাকতে পারে এবং আমি এই ম্যাপিংটি উল্টানোর লক্ষ্যটি অর্জন করার কোনও প্রয়োজন দেখিনি। সুতরাং এখানে ভুল উত্তর গৃহীত হয়েছে তা অর্থহীন - যদি কোনও গুগল অনুসন্ধান আপনাকে এখানে এনে দেয় তবে আপনি স্পষ্টতই ভুল প্রশ্ন জিজ্ঞাসা করছেন।
অ্যারন হল

1
এটি ডিবাগিংয়ের জন্য দুর্দান্ত ধারণা!
জন ktejik

উত্তর:


48

আপনি কি এটি করার চেষ্টা করছেন?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

উদাহরণ

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

1
rlotun নামটি আবিষ্কার করার অনুমতি দেয় বলে এটি এর প্রাথমিক "স্পিরিট" এর কাছাকাছি। আমি আপনার anwser উভয় ব্যবহার করতে পারে। অথবা টাইপ করতে কেবল আমার জঘন্য হাত ব্যবহার করুন। কিছু জিনিস কেবল সেই স্বয়ংক্রিয়রূপে তৈরি হয় না ...
ই-সন্তুষ্ট

7
@ ই-সন্তুষ্ট: @ rlotun এর কাজ করার জন্য আপনাকে ভেরিয়েবলের তালিকা সরবরাহ করতে হবে। আপনার যদি ভেরিয়েবলের তালিকা থাকে তবে তাদের নামগুলি "আবিষ্কার" করার বিষয়টি কী?
এসলট

4
স্থানীয় এবং গ্লোবালগুলি স্পষ্টভাবে ব্যবহার করার পরিবর্তে কেন স্পষ্ট?

1
@ রজার পেট: কারণ পুরো অনুশীলনের মূল বিষয়টি কী তা বুঝতে পারছিলাম না।
এসলট

242
এই উত্তর জিজ্ঞাসা করা প্রশ্নের উত্তর দেয় না। আপনার যদি ভেরিয়েবলের তালিকা থাকে তবে তাদের নামগুলি "আবিষ্কার" করার বিষয়টি কী? সদৃশতা এড়ানোর জন্য যাতে print('x: ' + x)একটি পরিবর্তে দুটি লিখতে পারে magic_print(x)এবং ভেরিয়েবলের নাম না লিখে একই আউটপুট পেতে পারে ।
পাইওটর ডব্রোগোস্ট

130

আনইন্ডাইন্ড যেমন বলেছিল, এটি পাইথনে আপনি যা করেন তা আসলে নয় - ভেরিয়েবলগুলি আসলে বস্তুর সাথে ম্যাপিংয়ের নাম।

তবে এটি চেষ্টা করার এবং করার একটি উপায় এখানে রয়েছে:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

14
এই ধারণার যোগ্যতা রয়েছে তবে নোট করুন যে দুটি ভেরিয়েবলের নাম একই মান (যেমন True) উল্লেখ করে তবে একটি অনিচ্ছাকৃত ভেরিয়েবলের নাম ফিরে আসতে পারে।
unutbu

14
এর id(v) == id(a)বদলে কেন v is a? এটি একাধিক ভেরিয়েবলের সাথে আবদ্ধ অবজেক্টের জন্য যেমন ব্যর্থ হবে, যেমন ইনটস, স্ট্রিং এবং অনুরূপভাবে প্রয়োগ করা ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলি।

হ্যাঁ, v is aএকটি ভাল পছন্দ হবে। এবং হ্যাঁ, উত্থিত হতে পারে এমন সমস্ত সম্ভাব্য সমস্যাগুলি দেওয়া নিঃসন্দেহে বিপজ্জনক! ;-)
rlotun

16
@ ই-সন্তুষ্ট আমি অবাক হয়েছি যে আপনি এই উত্তরটিকে উত্তর হিসাবে চিহ্নিত করেননি কারণ আমি আপনার মন্তব্যের সাথে একমত বলেছি যে রোল্টুন এটির প্রাথমিক "স্পিরিট" এর কাছাকাছি কারণ এটি নামটি আবিষ্কার করতে দেয় । অতিরিক্তভাবে এস.লোটের উত্তর আপনার প্রশ্নকে মোটেও উত্সাহ দেয় না ...
পাইওটর ডব্রোগস্ট

2
"ওভারকিল এবং বিপজ্জনক" ... এবং ইওল ব্যবহার না?
বাগ

63

আমি এটি অনেক কিছু করতে চেয়েছিলাম এই হ্যাকটি রলটুনের পরামর্শের সাথে খুব মিল, তবে এটি একটি ওয়ান-লাইনার, যা আমার কাছে গুরুত্বপূর্ণ:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

পাইথন 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

3
@ কেফলাভিচ আমি এই পদ্ধতিটি খুব পছন্দ করেছি এবং এখন সময়ে সময়ে ব্যবহার করেছি। তবে আমি এটি ভিতরে ফাংশন কাজ করতে না পারি। আমি অনুমান করি যে এটি করার আরও "আরও ভাল" উপায় আছে তবে এনবুবস যতটা সুন্দর করে দেয় তেমন কোনও সুন্দর নয়। আপনি কি কেফলাভিচ ফাংশনে এটি ব্যবহার করতে সক্ষম হয়েছেন? এই যেখানে আমি এই সম্পর্কে একটি প্রশ্ন জিজ্ঞাসা।
লিও

10
দ্রষ্টব্য যে পাইথন 3-এ, iteritems()প্রতিস্থাপন করা হয়েছেitems()
জোনাথন হুইলারের

এটি অবিশ্বস্ত: spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)আউটপুটspam
Andreasdr

1
@andreasdr এর কারণ এটি spam = 1, blah = 1; assert spam is blah। প্রাথমিক তথ্য প্রকারের সাথে তুলনা করার সময় সমাধানটি ভেঙে যায়।
JYun

17

এটি একটি হ্যাক। এটি সমস্ত পাইথন বাস্তবায়ন বিতরণে কাজ করবে না (বিশেষত, যাদের নেই traceback.extract_stack) do

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

মনে রাখবেন এই হ্যাকটি ভঙ্গুর:

make_dict(bar,
          foo)

(2 লাইনে মেক_ডিক্ট কল করা) কাজ করবে না।

পরিবর্তে অভি এর বাইরে জেনারেট করতে চেষ্টা মান foo এবং bar, এটা আরো অনেক কিছু Pythonic স্ট্রিং এর বাইরে অভি জেনারেট করতে হবে পরিবর্তনশীল নামের 'foo' এবং 'bar':

dict([(name,locals()[name]) for name in ('foo','bar')])

1
স্মার্ট হ্যাকের জন্য +1। অবশ্যই, ট্রেস ব্যাক খুব ধীর হয় তাই এটি ব্যবহার করা ঝিমঝিম হতে পারে।
ই-সন্তুষ্ট

1
+1111111 !!!! হ্যাঁ এটি ধীর, কিন্তু ব্যবহার করার সময় print("a_very_long_name: {}'.format(a_very_long_name))কে যত্ন করে!
frnhr

14

পাইথনে এটি সম্ভব নয়, যার সত্যই "ভেরিয়েবল" নেই। পাইথনের নাম রয়েছে এবং একই বস্তুর জন্য একাধিক নাম থাকতে পারে।


হ্যাঁ, আমি জানি, আমি প্রশ্নটি সহজ করে দিয়েছি, তবে আমি "get_var_tags (var) [0]" এর মতো আরও কিছু প্রত্যাশা করছিলাম।
ই-সন্তুষ্ট

10

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

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

সুতরাং আপনার যদি কিছু জটিল অভিধান / তালিকা / দ্বিপাক্ষিক পরিস্থিতি থাকে তবে দোভাষী আপনার দ্বারা নির্ধারিত পরিবর্তনশীল নামটি ফিরিয়ে দেওয়া বেশ সহায়ক হবে। উদাহরণস্বরূপ, এখানে একটি অদ্ভুত অভিধান:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

আমি এটিকে সঠিক জায়গায় রাখি কিনা তা নিশ্চিত নই, তবে আমি ভেবেছিলাম এটি সাহায্য করতে পারে। আমি এটা আশা করি।


সুতরাং আপনার মাথা পরীক্ষা করে, এটি কি ভেরিয়েবল / নামগুলি কোডের বিভিন্ন সময়ে বিভিন্ন জিনিসকে নির্দেশ করতে পারে এই সত্যের জন্য অ্যাকাউন্ট করে? উদাহরণস্বরূপ myconnection, এক পর্যায়ে একটি বুলিয়ান মান, অন্য সময়ে একটি পূর্ণসংখ্যার, এবং কোড নির্বাহের অন্য সময়ে একটি সকেট সংযোগের দিকে ইঙ্গিত করা যেতে পারে ??

9

আমি এই প্রশ্নের উত্তরের উপর ভিত্তি করে একটি ঝরঝরে সামান্য দরকারী ফাংশন লিখেছি। আমি এটি এখানে রাখছি যদি এটি কার্যকর হয়।

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

ব্যবহার:

>> a = 4
>> what(a)
a = 4
>>|

6

আমি দেখতে পাচ্ছি যে আপনার যদি ইতিমধ্যে মানগুলির একটি নির্দিষ্ট তালিকা থাকে তবে এটি @ এস দ্বারা বর্ণিত। লটগুলি সেরা; তবে নীচের বর্ণিত পদ্ধতিটি কোডের মধ্যে সমস্ত ভেরিয়েবল এবং ক্লাসগুলি যুক্ত করতে ভাল কাজ করে তবে ভেরিয়েবলের নাম দেওয়ার প্রয়োজন নেই যদিও আপনি চাইলে সেগুলি নির্দিষ্ট করতে পারেন। কোডগুলি ক্লাসগুলি বাদ দেওয়ার জন্য বাড়ানো যেতে পারে।

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

আউটপুট:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

6

পাইথন 3 এ এটি সহজ

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

এটি মুদ্রণ করবে:

myVariable 5


এই rlotun এর পদক্ষেপ কিন্তু একটি বিট simplier অনুরূপ
officialhopsof

10
-1। একটি নতুন দোভাষী উইন্ডো খুলুন এবং চেষ্টা করুন for v in locals()
এয়ার

আমি কী বলতে চাইছি তা পুরোপুরি নিশ্চিত নই?
অফিসিয়াল

4
এটি একটি ত্রুটি দেবে: রানটাইমঅরর: অভিধানটি পুনরাবৃত্তির সময় আকার পরিবর্তন করেছে ...
নিজার বি।

2
তবে আপনি এটি করতে পারেনfor v in list(locals()):
ফিলিইডা

5

Python3। কলিং লোকাল নেমস্পেস ক্যাপচার করতে ইন্সপেক্ট ব্যবহার করুন তারপরে এখানে উপস্থাপন করা আইডিয়াগুলি ব্যবহার করুন। যেমনটি উল্লেখ করা হয়েছে একের বেশি উত্তর দিতে পারে।

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

উত্তম উত্তর, তবে আমার পক্ষে এটি আরও ভাল: ... আইডি (নাম (কিছুই নয়, ফ্রেম.ফ_ব্যাক.ফ_লোকালস)) == ... ...
এমমানুয়েল ডুমাস

5

পরিবর্তনশীল নামগুলি পড়তে আমি এখানে তৈরি ফাংশনটি দিচ্ছি। এটি আরও সাধারণ এবং বিভিন্ন অ্যাপ্লিকেশনগুলিতে ব্যবহার করা যেতে পারে:

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

নির্দিষ্ট প্রশ্নে এটি ব্যবহার করতে:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

4

থ্রেডটি পড়ে, আমি দেখতে পেলাম এক ভয়াবহ ঘর্ষণ। একটি খারাপ উত্তর দেওয়া যথেষ্ট সহজ, তারপরে কাউকে সঠিক উত্তর দেওয়া হোক। যাইহোক, আমি যা পেয়েছি তা এখানে।

থেকে: [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )

নামগুলি কিছুটা পৃথক - সেগুলি সত্যই বস্তুর বৈশিষ্ট্য নয় এবং অবজেক্টটি নিজেই জানে না এটি কী বলে।

কোনও বস্তুর অনেকগুলি নাম থাকতে পারে, বা কোনও নামই থাকতে পারে না।

নামগুলি নেমস্পেসে থাকে (যেমন মডিউল নেমস্পেস, একটি উদাহরণ নেমস্পেস, একটি ফাংশনের স্থানীয় নেমস্পেস)।

দ্রষ্টব্য: যে এটি বলে যে বস্তু নিজেই জানে না এটি কী বলে , তাই এটি ক্লু ছিল। পাইথন অবজেক্টস স্ব-উল্লেখযোগ্য নয়। তারপরে এটি বলে, নামগুলি নেমস্পেসে থাকে । এটি আমাদের টিসিএল / টিকে রয়েছে। সুতরাং সম্ভবত আমার উত্তর সাহায্য করবে (তবে এটি আমাকে সাহায্য করেছিল)

    জেজে = 123
    প্রিন্ট eval ("'" + str (id (jj)) + "'")
    মুদ্রণ দির ()

166707048
['__ বিল্টিনস__', '__ডোক__', '__ফাইলে__', '__ নাম__', '__ প্যাকেজ__', 'জেজে']

সুতরাং তালিকার শেষে 'জেজে' রয়েছে।

কোডটি আবার লিখুন:

    জেজে = 123
    প্রিন্ট eval ("'" + str (id (jj)) + "'")
    এক্স ইন দির () এর জন্য:
        মুদ্রণ আইডি (alওয়াল (এক্স))

161922920
['__ বিল্টিনস__', '__ডোক__', '__ফাইলে__', '__ নাম__', '__ প্যাকেজ__', 'জেজে']
3077447796
136515736
3077408320
3077656800
136515736
161922920

কোড আইডির এই কদর্য বিট ভেরিয়েবলের নাম / অবজেক্ট / যাই হোক না কেন আপনি-পেডেন্টিকস-কল করুন।

সুতরাং, এটি আছে। আমরা যখন এটি সরাসরি অনুসন্ধান করি তখন 'jj' এর মেমরি ঠিকানাটি একই রকম হয়, যখন আমরা অভিধানটি বিশ্বব্যাপী নামের স্থানটিতে সন্ধান করি। আমি নিশ্চিত আপনি এটি করতে একটি ফাংশন করতে পারেন। আপনার ভেরিয়েবল / অবজেক্ট / উইপসিটি কোন নেমস্পেসে রয়েছে তা কেবল মনে রাখবেন।

Qed।


6
আপনি এখানে eval দুটি পাগল ব্যবহার আছে। প্রথম ঠিক হিসাবে একই: print id(jj)। দ্বিতীয়টি কেবল নামটি সন্ধান করে এবং আরও সহজেই এটি করা যায় vars()
নেড ব্যাচেল্ডার

2

সম্ভবত আমি এটিকে ওভারটিকিং করছি তবে ..

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

গ্রেট! এই আমি খুঁজছিলাম ছিল। ধন্যবাদ @ rh0dium ... \ Nvariable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
Majdi

2
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

2

আমি পাইপির সমাধান আপলোড করেছি । এটি একটি মডিউল যা সি # এর nameofকার্যকারিতার সমতুল্য সংজ্ঞা দেয় def

এটি ভেরিয়েবল / বৈশিষ্ট্যগুলির নাম পাঠিয়ে ফ্রেমের জন্য বাইকোডের নির্দেশাবলীর মাধ্যমে পুনরুক্ত হয় vari নাম পাওয়া যায় .argreprএর LOADফাংশন এর নাম নিম্নলিখিত নির্দেশাবলী।



1

বেশিরভাগ অবজেক্টের একটি __name__ নেই গুণ নেই। (ক্লাস, ফাংশন এবং মডিউলগুলি করে; আরও যে কোনও বিল্টিন ধরণের রয়েছে?)

তুমি আর কি আশা print(my_var.__name__)ছাড়া অন্যprint("my_var") ? আপনি কি কেবল স্ট্রিংটি সরাসরি ব্যবহার করতে পারবেন?

আপনি একটি ডিক "টুকরো টুকরো" করতে পারেন:

def dict_slice(D, keys, default=None):
  return dict((k, D.get(k, default)) for k in keys)

print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})

বিকল্পভাবে:

throw = object()  # sentinel
def dict_slice(D, keys, default=throw):
  def get(k):
    v = D.get(k, throw)
    if v is not throw:
      return v
    if default is throw:
      raise KeyError(k)
    return default
  return dict((k, get(k)) for k in keys)

2
+1 তবে আমি জানি যে নামটির কোন অস্তিত্ব নেই, কেন প্রত্যেকে এই "সাহিত্যের" কিছুটা সাহিত্যের সাথে নেয়? আপনার সমাধান সমস্যার সমাধান করতে পারে না কারণ আমি নামটি হরকোড করতে চাই না, Iর্ধ্বমুখী আমি ডিক সমাধানটি ইতিমধ্যে প্রশ্নটিতে দিয়েছি।
ই-সন্তুষ্ট

3
@ ই-সন্তুষ্ট: স্থানীয়দের মধ্যে যদি কেবলমাত্র সমস্ত কিছু ব্যবহার করা () আপনার সমস্যার সমাধান করে, আপনি কী জিজ্ঞাসা করছেন তা আমার কোনও ধারণা নেই। আমি তুমি ঠিক আছে অনুমান করছি কলিং সঙ্গে some_func(var), তাই আমি কাছ থেকে অনেক দূরে আছে না বাতলান করার চেষ্টা some_func("var"), সঙ্গে dictslice আপনি একই সময়ে একাধিক ভেরিয়েবল জন্য নাম-মান ম্যাপিং পেতে সক্ষম হবেন।

1

আচ্ছা, আমি খুব একই সম্মুখীন প্রয়োজন কয়েক দিন আগে এবং ছিল একটি পরিবর্তনশীল এর পেতে নাম যা প্রতি নির্দেশ ছিল বস্তুর নিজেই।

এবং কেন এটি এত প্রয়োজনীয় ছিল?

সংক্ষেপে আমি মায়ার জন্য একটি প্লাগ-ইন তৈরি করছিলাম । মূল প্লাগ-ইনটি সি ++ ব্যবহার করে নির্মিত হয়েছিল তবে জিইউআই পাইথনের মাধ্যমে অঙ্কিত হয়েছে (এটি প্রসেসরের নিবিড় হিসাবে নয়)। যেহেতু আমি, returnডিফল্ট ব্যতীত প্লাগ-ইন থেকে একাধিক মান কীভাবে জানি না MStatus, তাই পাইথনে একটি অভিধান আপডেট করতে আমাকে ভেরিয়েবলের নামটি পাস করতে হয়েছিল, জিইউআই প্রয়োগকারী অবজেক্টের দিকে ইঙ্গিত করে যা কোনটি অভিধানটি নিজেই, প্লাগ-ইনে অন্তর্ভুক্ত ছিল এবং তারপরে মায়ারMGlobal::executePythonCommand() বিশ্বব্যাপী অভিধান থেকে অভিধানটি আপডেট করতে ব্যবহার করুন ।

আমি যা করেছি তা করার মতো কিছু ছিল:

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

আমি জানি যে এটি globalsঅনেকগুলি কীতে নিখুঁত সমাধান নয় একই জিনিসটির দিকে ইঙ্গিত করতে পারে যেমন:

a = foo()
b = a
b.name()
>>>b
or
>>>a

এবং যে পদ্ধতির থ্রেড-নিরাপদ নয়। আমি ভুল হলে আমাকে সংশোধন করুন।

অন্ততপক্ষে এই পদ্ধতির ফলে বিশ্বব্যাপী এমন কোনও পরিবর্তকের নাম পেয়ে আমার সমস্যার সমাধান হয়েছে যা বস্তুটি নিজেই নির্দেশ করে এবং এটি অভ্যন্তরীণভাবে ব্যবহার করার জন্য এটি যুক্তি হিসাবে প্লাগ-ইনকে দেয়।

আমি এটি int(আদিম পূর্ণসংখ্যার শ্রেণি) চেষ্টা করে দেখলাম তবে সমস্যাটি হচ্ছে এই আদিম শ্রেণিগুলি বাইপাস করা হয় না (দয়া করে প্রযুক্তিগত পরিভাষাটি যদি ভুল হয় তবে এটি সংশোধন করুন)। আপনি পুনরায় বাস্তবায়ন করতে পারেন intএবং তারপরেও করতে পারেন int = fooতবে a = 3আদিমতার থেকে কখনই কোনও বস্তু হতে পারবেন না foo। এটি কাটিয়ে উঠতে আপনাকে কাজ a = foo(3)করতে হবে a.name()


1

পাইথন ২.7 এর সাথে আরও নতুন অভিধান অভিধানও রয়েছে যা এটিকে কিছুটা ছোট করে তোলে। যদি সম্ভব হয় তবে আমি উত্তরের পরিবর্তে ইওল (insteadভাল অশুভ) স্ব হ'ল কোনও বিষয় হতে পারে যা আপনার দেখার প্রেক্ষাপট রয়েছে। এটি কোনও বস্তু বা স্থানীয় লোকাল = স্থানীয় () ইত্যাদি হতে পারে

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

1

আমি একই সমস্যা নিয়ে কাজ করছিলাম। @ এস.লট বলেছেন, "আপনার যদি ভেরিয়েবলের তালিকা থাকে তবে তাদের নামগুলি" আবিষ্কার "করার কী দরকার?" এবং আমার উত্তরটি কেবল এটি করা যায় কিনা তা দেখার জন্য এবং যদি কোনও কারণে আপনি তালিকায় টাইপ করে আপনার ভেরিয়েবলগুলি বাছাই করতে চান। যাইহোক, আমার গবেষণায় আমি এই থ্রেডটি জুড়ে এসেছি এবং আমার সমাধানটি কিছুটা প্রসারিত এবং @rlotun সমাধানের উপর ভিত্তি করে। আরেকটি বিষয়, @ ইউনুটবু বলেছিলেন, "এই ধারণার যোগ্যতা রয়েছে, তবে মনে রাখবেন যে দুটি ভেরিয়েবলের নাম একই মান (যেমন সত্য) উল্লেখ করে তবে একটি অনিচ্ছাকৃত ভেরিয়েবলের নাম ফিরে আসতে পারে।" এই ব্যায়াম যে সত্য ছিল তাই আমি একটি তালিকা ধী প্রতিটি সম্ভাবনা এই অনুরূপ ব্যবহার করে এটি মোকাবেলা ইন: isClass = [i for i in isClass if i != 'item']। এটি ছাড়া "আইটেম" প্রতিটি তালিকায় প্রদর্শিত হবে।

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

আমি এটি নিয়ে যে বিষয়টি নিয়ে যাচ্ছি তা হ'ল নামগুলি কোনও বস্তুর বৈশিষ্ট্য নয়। একটি একক অবজেক্টের একাধিক নাম থাকতে পারে, বা কোনও নাম থাকতে পারে না। উদাহরণস্বরূপ, আপনি pi = pieনিজের কোডে যুক্ত করেছেন, আপনি আপনার isFloatতালিকায় একটি অতিরিক্ত এন্ট্রি পাবেন । আপনি যদি tuple_1[0]আপনার mixedDataTypesতালিকায় যুক্ত হন তবে আপনার কোডে দুবার "এক" থাকা সত্ত্বেও এর জন্য কোনও নাম খুঁজে পাওয়া যাবে না (যদিও স্ট্রিং ইন্টার্নিংয়ের জন্য ধন্যবাদ, তারা উভয়ই একই বস্তুর উল্লেখ হবে) be
ব্ল্যাকঙ্কহ্ট

1
@ ব্ল্যাককিংহিট --- আমি সম্মত এটি এমন কিছু করার কেবলমাত্র অন্য উপায় যা সত্যিই করা বোঝানো হয়নি। আমি বলিনি যে এটি অনন্য ফলাফল দেয় বা এটি অপূর্ণ। এটি করতে গিয়ে আমি জানতে পেরেছি যে ভেরিয়েবলগুলি ব্যবহার করা piএবং eহিসাবে অনাকাঙ্ক্ষিত আউটপুট ঘটায় এবং এটি উভয়ই mathগ্রন্থাগারের অংশ । আমার জন্য এটি কেবল একটি ব্যায়াম ছিল এটি দেখার জন্য যে শেষ ফলাফলটি নির্ভুল না হলেও এটি করা যেতে পারে could আমার এই ভাষাটি শেখার ক্ষেত্রে কেবল বইয়ের মধ্য দিয়েই যায়। আমার মতে, আপনি যদি ভাষাটি সত্যিই শিখতে চান তবে আপনাকে "কী যদি" ​​খেলতে হবে এবং আপনি কী নিয়ে এসেছেন তা দেখতে হবে।
মাইকেল সোয়ার্টজ

1

আপনি ইজিডিক্ট ব্যবহার করতে পারেন

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

আরেকটি উদাহরণ:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

1

পাইথন 3-এ, এই ফাংশনটি স্ট্যাকের বাইরের সর্বাধিক নামটি পাবেন:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

এটি কোডের যে কোনও জায়গায় কার্যকর। বিপরীত স্ট্যাকটিকে প্রথম ম্যাচের জন্য সন্ধান করে Tra


0

যদিও এটি সম্ভবত একটি ভয়ঙ্কর ধারণা, এটি রলটুনের উত্তর হিসাবে একই লাইন বরাবর রয়েছে তবে এটি প্রায়শই সঠিক ফলাফল ফিরে আসবে।

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

আপনি এটিকে এভাবে বলেছেন:

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

0

তালিকা পাওয়া উচিত তারপর ফিরে

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

0

এটি ভেরিয়েবলের নাম ফেরত দেবে না তবে আপনি সহজে গ্লোবাল ভেরিয়েবল থেকে অভিধান তৈরি করতে পারবেন।

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

0

python-varnameআপনি সহজেই এটি করতে পারেন সহ :

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

দাবি অস্বীকার: আমি সেই পাইথন-বর্ণের পাঠাগারটির লেখক।


-1
>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

এইভাবে সম্ভবত 'এ' বা 'বি' এর জন্য নাম পান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.