uisng a for loop to print a backwards list? - python-3.x

Below is my code I have printing this in ascending order I now need to print it in descending order but don't know how? I have tried the below code however it is not printing my desired results i.e Jill,8,1,0 first and soon
sorted_list = ["jack",4,3,1,"jill",8,1,0,"bob",0,0,10,"tim",5,3,1,"sod",3,1,0]
des_list = []
for i in range(len(sorted_list),2,-3,-1):
des_list.append(sorted_list[i-2])
des_list.append(sorted_list[i - 1])
des_list.append(sorted_list[i])
des_list.append(sorted_list[i+1])
print(des_list)

OP is incredibly vague and I can't determine any way in which the list provided is 'sorted' while a reversal of the list would print out 'jill' first. At any rate, I've assumed:
The strings are supposed to be names
The ints that follow are attributes of the aforementioned names
With that, I created a dict that holds the names and attributes. This would be sorting by alphabetical name with the attributes in their original order.
sorted_list = ["jack",4,3,1,"jill",8,1,0,"bob",0,0,10,"tim",5,3,1,"sod",3,1,0]
nameDict = {}
tmp = None
for _ in sorted_list:
if isinstance(_, str):
tmp = _
nameDict[tmp] = []
else:
if tmp: nameDict[tmp].append(_)
final = []
for name in list(reversed(sorted(nameDict))):
final += [name] + nameDict[name]
print final
While writing this, OP seems to have responded to my comment and apparently would like the attributes themselves in descending order.
sorted_list = ["jack",4,3,1,"jill",8,1,0,"bob",0,0,10,"tim",5,3,1,"sod",3,1,0]
nameDict = {} # empty dictionary {key1 : value1, key2 : value2 } etc...
tmp = None # temporary variable used to keep track of the name
for _ in sorted_list:
if isinstance(_, str): # if the name is a string...
tmp = _ # ... set the temporary variable to the name
nameDict[tmp] = [] # create an entry in the dictionary where the value is an empty list. Example: { "jill" : [] }
else:
if tmp: nameDict[tmp].append(_) # as long as tmp is not None, append the value to it. For example, after we hit "jill", it will append 8 then 1 then 0.
final = [] # empty list to print out
for name in nameDict: # loop through the keys in nameDict
final += [name] + sorted(nameDict[name], reverse=True) # append the name to the final list as well as the sorted (descending) list in the dictionary
print final
If you need the names in their correct order, that might be a bit different because dicts are unsorted.

Related

Check list for part of value and return whole value

I have a master list of ID numbers and another list of partial ID numbers. I need to check if the partial ID number is in the master list. If so, I need to return the whole ID number into a new list. What I have:
master_list = ['20000-K-A', '20000-K-B', '20000-K-C', '30000-R-X', '30000-R-V', '30000-R-F']
partial_list = [20000, 40000, 500000]
new_list =[]
for x in partial_list:
if x in master_list:
new_list.append(x)
print(new_list)
Now this only works if the partial ID number is EXACTLY what is in the master list. How do I return the value from the master list so that I can add it to the new list?
One option is to create a lookup dictionary first from master_list (note that the master_list is a list of strings while partial_list is a list of integers, so we need to cast the prefix to int):
d = {}
for item in master_list:
k, _ = item.split('-', maxsplit=1)
d.setdefault(int(k), []).append(item)
which looks like:
{20000: ['20000-K-A', '20000-K-B', '20000-K-C'],
30000: ['30000-R-X', '30000-R-V', '30000-R-F']}
Then iterate over partial_list to get the partially matching Ids:
new_list =[]
for x in partial_list:
new_list.extend(d.get(x, []))
Output:
['20000-K-A', '20000-K-B', '20000-K-C']

List Comprehension with "if" is not returning the same output as when I make a For Loop when counting the number of unique letters in a word

Can someone explain to me why there is a difference in output when using nested loops vs nested list comprehension?
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def unique_english_letters (word) :
unique = []
for i in word:
if i not in unique:
unique.append(i)
return len(unique)
print(unique_english_letters("mississippi"))
# outputs 4 (my expected output)
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def unique_english_letters (word) :
unique = []
unique = [i for i in word if i not in unique]
return len(unique)
print(unique_english_letters("mississippi"))
#outputs 11 (length of mississippi"
^ Output
In the second example, this:
unique = []
unique = [i for i in word if i not in unique]
is equivalent to:
unique = [i for i in word if i not in []]
unique is an empty list while the list comprehension is evaluated, and then unique is re-assigned the results.
To do what you want in simple terms, use a set which can only contain unique values, and use set intersection(& operator) to generate the set of letters contained in word:
letters = set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
def unique_english_letters(word):
return len(letters & set(word))
print(unique_english_letters("mississippi"))
# output: 4

Python losing track of index location in for loop when my list has duplicate values

I'm trying to iterate over pairs of integers in a list. I'd like to return pairs where the sum equals some variable value.
This seems to be working just fine when the list of integers doesn't have repeat numbers. However, once I add repeat numbers to the list the loop seems to be getting confused about where it is. I'm guessing this based on my statements:
print(list.index(item))
print(list.index(item2))
Here is my code:
working_list = [1,2,3,4,5]
broken_list = [1,3,3,4,5]
def find_pairs(list, k):
pairs_list = []
for item in list:
for item2 in list:
print(list.index(item))
print(list.index(item2))
if list.index(item) < list.index(item2):
sum = item + item2;
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
### First parameter is the name is the list to check.
### Second parameter is the integer you're looking for each pair to sum to.
find_pairs(broken_list, 6)
working_list is fine. When I run broken_list looking for pairs which sum to 6, I'm getting back (1,5) but I should also get back (3,3) and I'm not.
You are trying to use list.index(item) < list.index(item2) to ensure that you do not double count the pairs. However, broken_list.index(3) returns 1 for both the first and second 3 in the list. I.e. the return value is not the actual index you want (unless the list only contains unique elements, like working_list). To get the actual index, use enumerate. The simplest implementation would be
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for j, item2 in enumerate(list):
if i < j:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
For small lists this is fine, but we could be more efficient by only looping over the elements we want using slicing, hence eliminating the if statement:
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for item2 in list[i+1:]:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
Note on variable names
Finally, I have to comment on your choice of variable names: list and sum are already defined by Python, and so it's bad style to use these as variable names. Furthermore, 'items' are commonly used to refer to a key-value pair of objects, and so I would refrain from using this name for a single value as well (I guess something like 'element' is more suitable).

Assign matched item in list to a variable

The motive is to check if any of items in a list are contained in another list, and in case there is a match, assign it to a variable in a 'pythonic' fashion
if any('a','b','c') in ['b','x','y','z']:
#now i want to assign the matched 'b' to a variable concisely.
#In case of multiple matches , any match/ first match may be assigned
I want to avoid this :
lst = ['b','x','y','z']
if 'a' in lst:
var = 'a'
elif 'b' in lst"
var = 'b'
# and so on
You can use a function that returns either the first matched element or None in case no matched elements are found:
li_1 = ['a','b','c']
li_2 = ['b','x','y','z']
def find(li_1, li_2):
for e in li_1:
if e in li_2:
return e
print(find(li_1, li_2))
# b
print(find(['a'], ['b']))
# None
Note that this is an O(n^2) solution. If the items are hashable you can get an O(1) solution using sets intersection (and as a bonus you will get all matched elements):
li_1 = ['a','b','c']
li_2 = ['b','x','y','z']
s1 = set(li_1)
s2 = set(li_2)
print(s1.intersection(s2)) # or print(s1 & s2)
# {'b'}

Is there a way to test if two separate values, in two separate arrays, and check if they are equal or not?

Im trying to see if a value in one array is equal to that in another array, the values are integer values.
Ive tried turning them into string and integers from the array but get the error that they cannot be converted implicitly.
winningnumber = []
usernumber = []
print(winningnumber)
print(usernumber)
if(winningnumber == usernumber):
print("Exact number")
I would then get an output like so
[1]
['1']
In order to do this, what you want to do is access the first item of each array, and compare that value.
There are a lot of ways to do this, but here is a little driver program to show you one way.
# Defining a function to see if they match
def is_winning(arr1, arr2):
# Grabbing the first element in each array
# denoted by the [0], for the "0th" element
arr1_first_ele = arr1[0]
arr2_first_ele = arr2[0]
# If the first element in the first array matches the first element in the second
if arr1_first_ele == arr2_first_ele:
# Print out they match
print("They match")
# Otherwise
else:
# Print out that they dont
print("They don't match")
def main():
# Example arrays
test_array_one = [1,3,4]
test_array_two = [5,4,3]
# This should print out "They don't match"
is_winning(test_array_one, test_array_two)
# Example arrays
test_array_three = [6,7,8]
test_array_four = [6,5,4]
# This should print out "They match"
is_winning(test_array_three, test_array_four)
main()
This evaluates to:
They don't match
They match

Resources