Simpler way to create dictionary of separate variables?

前端 未结 27 1889
名媛妹妹
名媛妹妹 2020-11-22 02:42

I would like to be able to get the name of a variable as a string but I don\'t know if Python has that much introspection capabilities. Something like:

>&         


        
相关标签:
27条回答
  • 2020-11-22 03:24

    Here's the function I created to read the variable names. It's more general and can be used in different applications:

    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]
    

    To use it in the specified question:

    >>> foo = False
    >>> bar = True
    >>> my_dict = {get_variable_name(foo):foo, 
                   get_variable_name(bar):bar}
    >>> my_dict
    {'bar': True, 'foo': False}
    
    0 讨论(0)
  • 2020-11-22 03:24

    With python 2.7 and newer there is also dictionary comprehension which makes it a bit shorter. If possible I would use getattr instead eval (eval is evil) like in the top answer. Self can be any object which has the context your a looking at. It can be an object or locals=locals() etc.

    {name: getattr(self, name) for name in ['some', 'vars', 'here]}
    
    0 讨论(0)
  • 2020-11-22 03:25

    Python3. Use inspect to capture the calling local namespace then use ideas presented here. Can return more than one answer as has been pointed out.

    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
    
    0 讨论(0)
  • 2020-11-22 03:26

    Are you trying to do this?

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

    Example

    >>> 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}
    
    0 讨论(0)
  • 2020-11-22 03:26

    should get list then return

    def get_var_name(**kwargs):
        """get variable name
            get_var_name(var = var)
        Returns:
            [str] -- var name
        """
        return list(kwargs.keys())[0]
    
    0 讨论(0)
  • 2020-11-22 03:27

    I was working on a similar problem. @S.Lott said "If you have the list of variables, what's the point of "discovering" their names?" And my answer is just to see if it could be done and if for some reason you want to sort your variables by type into lists. So anyways, in my research I came came across this thread and my solution is a bit expanded and is based on @rlotun solution. One other thing, @unutbu said, "This idea has merit, but note that if two variable names reference the same value (e.g. True), then an unintended variable name might be returned." In this exercise that was true so I dealt with it by using a list comprehension similar to this for each possibility: isClass = [i for i in isClass if i != 'item']. Without it "item" would show up in each list.

    __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 []
    '''
    
    0 讨论(0)
提交回复
热议问题