Filtering a tuple with another tuple in Python

I have a list of tuples created using the zip function. zip combines four lists: narrative , subject , activity and filer , each of which is only a list of 0s and 1s. Let's say these four lists look like this:

 narrative = [0, 0, 0, 0] subject = [1, 1, 0, 1] activity = [0, 0, 0, 1] filer = [0, 1, 1, 0] 

Now I'm zip combining them to get a list of booleans indicating whether any of them are True .

ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)]

The problem that I am facing right now is to get a second list of tuples for which variable names are returned if it had 1 during the iteration. I assume it will look something like this:

 variables = ("narrative", "subject", "activity", "filer") reason = [", ".join([some code to filter a tuple]) for x in zip(narrative, subject, activity, filer)] 

I just can't figure out how I would do it. My desired result would look like this:

 reason # ["subject", "subject, filer", "filer", "subject, activity"] 

I'm a little new to Python, so I apologize if this is easy.

+5
source share
4 answers

Store tuples in a dictionary for a cleaner solution:

 tups = {'narrative': narrative, 'subject': subject, 'activity': activity, 'filer': filer} 

Decision:

 reason = [', '.join(k for k, b in zip(tups, x) if b) for x in zip(*tups.values())] 

It can also be written using itertools.compress :

 from itertools import compress reason = [', '.join(compress(tups, x)) for x in zip(*tups.values())] 

The solutions mentioned above do not preserve the order of tuples, for example. they can return something like

 ['subject', 'filer, subject', 'filer', 'activity, subject'] 

If you need to save the order, use collections.OrderedDict , as shown below:

 from collections import OrderedDict tups = OrderedDict([ ('narrative', narrative), ('subject', subject), ('activity', activity), ('filer', filer) ]) # The result is ['subject', 'subject, filer', 'filer', 'subject, activity'] 

EDIT: A solution that does not include dictionaries:

 from itertools import compress reason = [', '.join(compress(variables, x)) for x in zip(narrative, subject, activity, filer)] 

Consider using dictionaries if calling zip(...) no longer suitable for a single line.

+3
source

Using zip(narrative, subject, activity, filer) basically carries the matrix (your list of lists of equal lengths makes the matrix). Then you list them to find the location n , where the flag is true, and index the corresponding variable.

 narrative = [0, 0, 0, 0] subject = [1, 1, 0, 1] activity = [0, 0, 0, 1] filer = [0, 1, 1, 0] variables = ("narrative", "subject", "activity", "filer") # ======================================================== new_list = [[variables[n] for n, flag in enumerate(indicators) if flag] for indicators in zip(narrative, subject, activity, filer)] >>> new_list [['subject'], ['subject', 'filer'], ['filer'], ['subject', 'activity']] 

To see the transpose:

 >>> [i for i in zip(narrative, subject, activity, filer)] 
+1
source

You can simply use the understanding syntax filtering aspect to get your vaiable English name only if the corresponding flag is True:

 variables = ("narrative", "subject", "activity", "filer") [tuple (name for flag, name in zip(x, variables) if x) for x in zip(narrative, subject, activity, filer)] 

However, there is something suspicious about your approach - you would probably be much better off with an object-oriented approach, rather than trying to manually coordinate independent sequences of variables for each of your subjects.

0
source
  narrative = [0, 0, 0, 0] subject = [1, 1, 0, 1] activity = [0, 0, 0, 1] filer = [0, 1, 1, 0] variables = ("narrative", "subject", "activity", "filer") ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)] output = [] [[output.append(variables[j]) if t==1 else None for j,t in enumerate(x)] for x in zip(narrative, subject, activity, filer)] print ny_nexus print output 

Of course, you can simply do the following without using lists:

  narrative = [0, 0, 0, 0] subject = [1, 1, 0, 1] activity = [0, 0, 0, 1] filer = [0, 1, 1, 0] variables = ("narrative", "subject", "activity", "filer") ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)] output = [] for x in zip(narrative, subject, activity, filer): for j,t in enumerate(x): output.append(variables[j]) print ny_nexus print output 
0
source

Source: https://habr.com/ru/post/1243597/


All Articles