简体   繁体   中英

Python: how do I iterate only if value is a tuple/list and not a string

I am currently trying to write a python script/small app that is supposed to read events, and then translate them to a different format. I am also making us of this to dabble a bit in object oriented programming but I am far from an an expert.

I am trying to use a dictionary as map to define the mapping between the source fields and the translated fields.

One of the source fields though (priority in the example) is required twice in the output.

class event():
    def __init__(self, description, priority):
        self.description = description
        self.priority = priority

        pass

    _translateMap = {
       'description': 'message',
       'priority' : ('priority', 'severity')
    }

    def translate(self):
       result = {}
       for key, value in self._translateMap.items():
           for field in value:
               result[field] = getattr(self, key)

       return result

if __name__ == '__main__':
    event1 = event('blahblah','3')
    print event1.translate()

this will print: {'a': 'blahblah', 'e': 'blahblah', 'severity': '3', 'g': 'blahblah', 'm': 'blahblah', 'priority': '3', 's': 'blahblah'}

what I would like to have though is: {'message': 'blahblah', 'severity': '3', 'priority': '3'}

I understand that the problem is iterating through every character of 'message', I am not really sure though what is the best way to avoid this while still being able to parse multiple input values?

or is my expectation that they should work similarly is fundamentally wrong? As mentioned I'm not very experienced yet so if you think the approach doesn't make sense let me know!

Thank you in advance,

There are two ways you could fix this, you can make the 'message' string into a tuple, so your _translateMap would look like this:

_translateMap = {
    'description': ('message',),
    'priority' : ('priority', 'severity')
}

Otherwise, you could check the type with isinstance each time like this:

def translate(self):
    result = {}
    for key, value in self._translateMap.items():
        if isinstance(value,str):
            result[value] = getattr(self, key)
        else:
            for field in value:
                 result[field] = getattr(self, key)

    return result

I hope this helps. :)

You can test whether the value is a string using isinstance:

def translate(self):
    result = {}
    for key, value in self._translateMap.items():
        if isinstance(value,str):
            result[value] = getattr(self, key)
        else:
            for field in value:
                result[field] = getattr(self, key)

    return result

You don't need to have pass in the init dunder method. - Also, indentation is the most important aspect when it comes to python since it interprets code based on the latter. - You can pass numbers to functions without using single quotes (string).

You can do something on the lines of:

def translate(self):
   return {field: getattr(self, value) for value, field in self._translateMap.items()}

Although I don't understand why you set the priority field as a tuple, you can do something like:

class event():
    _translateMap = {
        'description': 'message',
        'priority': 'priority',
        'severity': 'severity'
    }


    def __init__(self, description, priority, severity):
        self.description = description
        self.priority = priority
        self.severity = severity

    def translate(self):
       return {field: getattr(self, value) for value, field in self._translateMap.items()}

if __name__ == '__main__':
    event1 = event('blahblah', 3, 5)
    print(event1.translate())

Give attention to how the numbers are not passed as strings and also if you'd like to add checks to the translate function you can.

I'm not sure about your use case but this will print the result as you want. You don't need to iterate through the variables. simply map everything you want in the first place.

class event():
    def __init__(self, description, priority):
        self.description = description
        self.priority = priority
        self.severity = priority

        pass

    _translateMap = {
       'description': 'message',
       'priority' : 'priority',
       'severity': 'severity'
    }

    def translate(self):
       result = {}
       for key, value in self._translateMap.items():
               result[key] = getattr(self, key)

       return result

if __name__ == '__main__':
    event1 = event('blahblah','3')
    print (event1.translate())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM