Larry,

i waited patiently to see what others will write and perhaps see if you explain 
better what you need. You seem to gleefully swat down anything offered. So I am 
not tempted to engage.

Some later messages suggest you may not be specifying quite what you want. It 
sounds like you are asking for something like a function that combines two 
things a certain way. Initially it sounded like two simple lists of any length 
and something like this was proposed:

[(f, s) for f in os for s in region]

It returns a list of tuples, but could just as easily return a list of lists or 
dictionary or  other variants.

You pointed out, validly, that if either of the original lists is empty, it 
fails. True. 

But that opens the question of what happens when any random thing is thrown 
there such as "hello" which Python happily treats as ['h', 'e', 'l', 'l', 'o'] 
for this purpose. You now seem to want a bulletproof solution that might start 
with a very basic function like this but add more checks and deal appropriately:

def combine_2(first, second):
    l_first = len(first)
    l_second =  len(second)

    if ( l_first + l_second == 0 ): return([])
    if ( l_first == 0 ): return(second)
    if ( l_second == 0 ): return(first)
    return([(f, s) for f in first for s in second])

The above works fine if I give it [] for one or both but maybe not. It returns 
an empty list if both are empty, which may be what you want or you may want an 
error or an empty tuple, ...

You wanted tuples in return. But if either one is empty, the above returns the 
original, a list without tuples. To return the valid list with each element as 
a singleton tuple could easily be done but you have not initially specified the 
expected behavior.

And it is hard to guess as it is not clear what you will do with this. Do you 
want to be able to do this for more than 2 at a time? At some point, the above 
approach is not right and an approach that works for an arbitrary number of 
lists to combine may make sense. Some python modules do something similar to 
the R function expand.grid() that makes all combinations into rows of a 
data.frame such as this expand_grid in the pandas module: 

https://pandas.pydata.org/pandas-docs/version/0.17.1/cookbook.html#creating-example-data

I assume that could be used as-is in some applications but could also be easily 
converted back into a list of tuples or have a generator deliver one result 
each time ...

And, yes, the above approach needs to convert your arguments into a single 
dictionary but that is easy enough. Getting back a list of lists horizontally 
may be something like this:

 df.values.tolist()

As others have pointed out, you are actually not stating what you want and are 
getting the right answer if you ALLOW any of your items to be empty. It is like 
any operation using an NaN or an Inf do not work well as the result is 
generally nonsense. If you do not want any empty sets, take care to exclude 
them. In my dictionary example above, you might add only non-empty lists to the 
dictionary, for example, and if the dictionary remains empty, then there is 
nothing to combine.

I also see a subtle requirement that is annoying. You want the NAME of each 
entry preserved in order even as some may be EMPTY. So i ask where these names 
are stored so you can communicate them. This is trivial in languages like R but 
perhaps not in Python without some help. My suggestion is that numpy/pandas and 
their data types can help. Once you make a structure like I describe above, the 
columns have headers you can ask about and then you can pass the headers of 
surviving entities that perfectly match the columns, even if you take the 
columns out into a list of tuples.

It looks to some like you want lots of things without being willing to earn 
them. Any number of methods will easily remove or filter what you keep. Once 
you have clean data, the remainder can be trivial.

You then supplied a solution you said worked fine that looked pretty much 
NOTHING like what we have been discussing:

def query_lfixer(query):
    for k, v in query.items():
        if type(v)==list:
            query[k] = {"$in": v}
    return query

self._db_conn[collection_name].find(query_lfixer(query))


The above code seems be taking a dictionary and modifying it? And what you 
needed in the end was a dictionary? So why did so many of us bother? I will 
keep that in mind for future questions.
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to