简体   繁体   中英

Special Operation on each element of array

I am trying to write out data in a very specific format including numbers, dates, strings. My input is an array containing this data but not necessarily in the right format. So I need to apply custom operations on almost every element. The input and output have variable length.

edit: A little bit more clarification here: I am parsing data from different sources with different formats. The task is to write them out to the same format. I am writing a default parser for each source. There is no way around that. I am writing the data into a format that contains all necessary fields for the output. eg [name, data, value, cur1, cur2, ...] Now I need to format this data in a very specific way . Eg Add something to the name. Basically I need to modify every element in my array in a rather unique way based on the index.

The input could look something like that:

arr = ['name', 30.09.2019, 20.5, 'EUR', 'USD', ....]
# or
arr = ['name', 30.09.2019]
# or
arr = ['name', '', '', '', '', 'note', '17.5', '',....]

And then I need to apply some functions to each element. The only solution I could come up with would be:

for i in range(0, len(arr)):
   if(i == 0):
      process_zero(arr[i])
   elif(i == 1):
      process_one(arr[i])
   ...

If it wasn't variable length I could do something like this:

process_zero(arr[0])
process_one(arr[1])
...

Is there a better/cleaner way to do this?

Since the array is variable length, it sounds like it's not really an appropriate structure in which to put your data. Make a dictionary or a class (or for Python >=3.7, a dataclass ) that contains your data in a more structured format.

# With dictionaries
sample = {'name' : 'Jane', 'USD' : 3.50, ... }

def myfunc(data_dict):
    data_dict['name'] = data_dict['name'].upper()
    data_dict['USD'] += 1
    ...

myfunc(sample)

# With classes
class MyClass:
    def __init__(self, name = '', USD = 0, ...):
        self.name = name
        self.USD = USD
        ...

    def myfunc(self):
        self.name = self.name.upper()
        self.USD += 1
        ...

sample = MyClass('Jane', 3.5, ...)
sample.myfunc()

Since the decision of which behavior you want is based entirely on the index of the element, you could make a list of functions that correspond to the elements in the array. How complicated this is depends on the variety of behavior and how important validation of each data type is. Looking at your latest example, it seems like you will need to at least check for empty strings.

Then you can simply zip() the list with the functions and call them. Your function list will need to have as many functions as element in the longest data you hope to process. If you zip with a sorter set of data it will work fine -- a longer set will ignore the extra data.

For example:

# Some function to handle particular types of data
def processNum(n):
    if n is None:
        print("no value")
        return
    try:
        n = float(n)
        n *= 3
        return f'Handle number: {n}'
    except ValueError:
        return "Bad input"

def currency(c):
    if isinstance(c, str) and c != '':
        return f'currency in: {c}'

# list of functions to apply (expecting at most 5 items to process)
processors = [
    lambda x: "Processed - 1: " + x,
    lambda x: "Processed - 2:" + x,
    processNum,
    currency,
    currency
]

Then you can call them in a loop:

arr = ['name', '30.09.2019', 30.5, 'EUR', 'USD']
for f,a in zip(processors, arr):
    print(f(a))

or, if you want a new list, in a comprehension:

[f(a) for f,a in zip(processors, arr)]

Result

['Processed - 1: name',
 'Processed - 2:30.09.2019',
 'Handle number: 91.5',
 'currency in: EUR',
 'currency in: USD']

Obviously the details will depend on how you need to process each item.

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