Check if a number exists in another list in python - python

I have two lists which contain the following type of information.
List #1:
Request = ["1/1/1.34", "1/2/1.3.5", "1/3/1.2.3", ...same format elements]
List #2:
Reply = ["1/1/0", "1/3/1", "1/2/0", ...same format elements]
From the "Reply" list, I want to be able to compare the second item in the "#/#/#", in this case it will be 1,3,2, and so on with all the items in the Reply list and check if there is a match with the second item in "Request list".
If there is a match, then I want to be able to return a new list which would contain the information of the third index in the request string appended with the third index of the matching string in the reply.
The result would be like the following.
Result = ["1.34.0", "1.3.5.0", "1.2.3.1"]
Note that the 0 was appended to the 1.34, the 1 was appended to the 1.3.4 and the 0 was appended to the 1.2.3 from the corresponding indexes in the "Reply" list as the second index existed in the "Reply" list. The 'Reply" list could have the item anywhere placed in the list.
I am unable to figure out a simple way to compare both the list one by one element for the second index. I am really confused and I would be grateful if anyone could give help me out here.
Thanks

You can also build it with list comprehension and string comparison:
res = [f"{i.split('/')[-1]}.{j.split('/')[-1]}" \
for i in Request for j in Reply \
if i.split('/')[1] == j.split('/')[1] ]
res
Out[1]:
['1.34.0', '1.3.5.0', '1.2.3.1']

You could try getting only the items you're interested in and then comparing. Something like this:
iRequest = {}
for x in Request:
iRequest[x.split('/')[1]] = x
That would give you a dictionary looking like this:
{'1':'1/1/1.34', '2':'1/2/1.35', ...and so on}
After doing the same but with the Reply list, you could go through every item in the new iReply (or whatever you choose to call it) dictionary and check if it is in iRequest. Eg:
similar = []
for x in iReply:
if x in iRequest:
similar.append(iReply[x])

Related

Segregate the list based on condition that starts with same pattern `string`

I have below list where i would like to segregate based on condition where all strings that starts with same string would become a newlist
Eg:-
list1 = ["glibc-2.11.3/include/sys/file.h", "glibc-2.11.3/include/sys/ioctl.h", "glibc-2.11.3/lib/crtn.o", "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h" , "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h", "test-3.7.10/asm/posix_types.h", "test-3.7.10/dsm/posix_types.h"]
Here is my try:-
list1 = ["glibc-2.11.3/include/sys/file.h", "glibc-2.11.3/include/sys/ioctl.h", "glibc-2.11.3/lib/crtn.o", "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h" , "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h"]
element = list1[0].split("/")[0]
newlist = []
for i in list1:
if i.startswith(element):
newlist.append(i)
print newlist
o/p:- ['glibc-2.11.3/include/sys/file.h', 'glibc-2.11.3/include/sys/ioctl.h', 'glibc-2.11.3/lib/crtn.o']
I get the 1st set of paths that starts with same string. I need to loop over for other remaining sets.
Basically What i am looking is , for a 1st iteration i am expecting to get all paths that starts with glibc-2.11.3 and for 2nd iteration all paths that starts with linux-libc-headers-2.6.32..so on. Actually i need to perform some check on set of same paths (starts with same string) that gets returned. Please help!
Use a dictionary to keep track of your filepaths
list1 = ["glibc-2.11.3/include/sys/file.h", "glibc-2.11.3/include/sys/ioctl.h", "glibc-2.11.3/lib/crtn.o", "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h" , "linux-libc-headers-2.6.32/asm-generic/bitsperlong.h", "test-3.7.10/asm/posix_types.h", "test-3.7.10/dsm/posix_types.h"]
directories = {}
for filepath in list1:
key = filepath.split("/")[0]
directories.setdefault(key, []).append(filepath)
print(directories)
Outputs:
{'glibc-2.11.3': ['glibc-2.11.3/include/sys/file.h',
'glibc-2.11.3/include/sys/ioctl.h',
'glibc-2.11.3/lib/crtn.o'],
'linux-libc-headers-2.6.32': ['linux-libc-headers-2.6.32/asm-generic/bitsperlong.h',
'linux-libc-headers-2.6.32/asm-generic/bitsperlong.h'],
'test-3.7.10': ['test-3.7.10/asm/posix_types.h',
'test-3.7.10/dsm/posix_types.h']}
list(directories.items()) would give you the list of lists you were trying to create, but instead of doing that you can just use directories.items() the exact same way you would use a list of lists.
dictionary.setdefault(key, []) is a quirky way of saying give me the list at this dictionary key or if there is not already a list there, create a new list and save it in the dictionary under this dictionary key and then give me that. documentation.

How to read and print a list in a specific order/format based on the content in the list for python?

New to python and for this example list
lst = ['<name>bob</name>', '<job>doctor</job>', '<gender>male</gender>', '<name>susan</name>', '<job>teacher</job>', '<gender>female</gender>', '<name>john</name>', '<gender>male</gender>']
There are 3 categories of name, job, and gender. I would want those 3 categories to be on the same line which would look like
<name>bob</name>, <job>doctor</job>, <gender>male</gender>
My actual list is really big with 10 categories I would want to be on the same line. I am also trying to figure out a way where if one of the categories is not in the list, it would print something like N/A to indicate that it is not in the list
for example I would want it to look like
<name>bob</name>, <job>doctor</job>, <gender>male</gender>
<name>susan</name>, <job>teacher</job>, <gender>female</gender>
<name>john</name>, N/A, <gender>male</gender>
What would be the best way to do this?
This is one way to do it. This would handle any length list, and guarantee grouping no matter how long the lists are as long as they are in the correct order.
Updated to convert to dict, so you can test for key existence.
lst = ['<name>bob</name>', '<job>doctor</job>', '<gender>male</gender>', '<name>susan</name>', '<job>teacher</job>', '<gender>female</gender>', '<name>john</name>', '<gender>male</gender>']
newlst = []
tmplist = {}
for item in lst:
value = item.split('>')[1].split('<')[0]
key = item.split('<')[1].split('>')[0]
if '<name>' in item:
if tmplist:
newlst.append(tmplist)
tmplist = {}
tmplist[key] = value
#handle the remaining items left over in the list
if tmplist:
newlst.append(tmplist)
print(newlst)
#test for existance
for each in newlst:
print(each.get('job', 'N/A'))

How to dynamically append to array in dict?

This has taken me over a day of trial and error. I am trying to keep a dictionary of queries and their respective matches in a search. My problem is that there can be one or more matches. My current solution is:
match5[query_site] will already have the first match but if it finds another match it will append it using the code below.
temp5=[] #temporary variable to create array
if isinstance(match5[query_site],list): #check if already a list
temp5.extend(match5[query_site])
temp5.append(match_site)
else:
temp5.append(match5[query_site])
match5[query_site]=temp5 #add new location
That if statement is literally to prevent extend converting my str element into an array of letters. If I try to initialize the first match as a single element array I get None if I try to directly append. I feel like there should be a more pythonic method to achieve this without a temporary variable and conditional statement.
Update: Here is an example of my output when it works
5'flank: ['8_73793824', '6_133347883', '4_167491131', '18_535703', '14_48370386']
3'flank: X_11731384
There's 5 matches for my "5'flank" and only 1 match for my "3'flank".
So what about this:
if query_site not in match5: # here for the first time
match5[query_site] = [match_site]
elif isinstance(match5[query_site], str): # was already here, a single occurrence
match5[query_site] = [match5[query_site], match_site] # make it a list of strings
else: # already a list, so just append
match5[query_site].append(match_site)
I like using setdefault() for cases like this.
temp5 = match5.setdefault(query_site, [])
temp5.append(match_site)
It's sort of like get() in that it returns an existing value if the key exists but you can provide a default value. The difference is that if the key doesn't exist already setdefault inserts the default value into the dict.
This is all you need to do
if query_site not in match5:
match5[query_site] = []
temp5 = match5[query_site]
temp5.append(match_site)
You could also do
temp5 = match5.setdefault(query_site, [])
temp5.append(match_site)
Assuming match5 is a dictionary, what about this:
if query_site not in match5: # first match ever
match5[query_site] = [match_site]
else: # entry already there, just append
match5[query_site].append(temp5)
Make the entries of the dictionary to be always a list, and just append to it.

Python string/float comparison

I've run into the following issue, with my code below. Basically I have a list of objects with an id and a corresponding weight, and I have another list of id's. I want to use only the weights of the objects matching the id's in the second list.
d_weights = [{'d_id':'foo', 'weight': -0.7427}, ...]
d_ids = ['foo', ...]
for dtc_id in d_ids:
d_weight = next((d['weight'] for d in d_weights if d['d_id'] == dtc_id), "")
print str(d_weight)
if str(d_weight) != "":
print "not empty string! "+str(d_weight)
The output for this is:
-0.7427
0.0789
-0.0039
-0.2436
-0.0417
not empty string! -0.0417
Why is only the last one not empty when I can print them fine and they are obviously not equal to an empty string? How do I check that the next() actually returned something before using it?
You haven't correct algorithm.
So d_weight = next((d['weight'] for d in d_weights if d['d_id'] == dtc_id), "") iterate only once.
On every cycle for weight_dict in d_weights: you've got only first dict of d_weights.
Without more data, i can't reproduce your output.
In my case it works fine:
-0.7427
not empty string! -0.7427
-0.327
not empty string! -0.327
Correct code you can find in DhiaTN's answer.
just iterate of the list of the keys and get the values from each dict :
for weight_dict in d_weights
for key in d_ids:
print weight_dict.get(key, "")

How can I call all items in a list item?

So in django, lets say you create a list through .append like so:
group = []
people = humans.objects.all()
for X in people:
X.update(name = Bob)
group.append(X.idnum)
If you wanted to get some of the items in the group list without it displaying like this " u'23' ",
you would have to call group[0] or any othe number to find the one youre looking for. My question is how can I get all of them at once without the u''. So if i have three peope in the group, I want their idnums to come out as 232528 instead of " u'23' u'25' u'28' " without me haveing to do group[0][1][2] since I want always know how many are in the list.
You want the str.join method. https://docs.python.org/2/library/stdtypes.html#str.join
"".join(group)
or if you want a number instead of a string
int("".join(group))
I would use a iteration and then add the string together:
list = [...]
result = ''
for item in list:
result += str(item)
The result would be '232528' if the items in the list are u'23' u'25' u'28'

Categories