Finding nth digit of a number in a list - python

Say you have some nested list
[[4,682,31249,81,523],[321741245,7],[349,25,5]]
where each element can be of any length and the length of each number can vary also. How can one check each individual number for what the first digit from the left contains? As well as continuing through the number to find the 2nd, 3rd, etc digit.
For simplicity, the program just needs to return one digit at a time, i.e. returns 4, then 6 when called again.
Expected output:
4,6,3,8,5,3,7,3,2,5
8,1,1,2,2,4,5
2,2,3,1,9

x=[[4,682,31249,81,523],[321741245,7],[349,25,5]]
x=[item for sublist in x for item in sublist]
max_len=len(str(max(x)))
x=[str(y) for y in x]
def digits(x,index):
digit_list=[]
for num in x:
try:
digit_list.append(num[index])
except:
pass
return digit_list
for index in range(0,max_len):
print(digits(x,index))
Explanation:
1.Intialize x
2.Flat x i.e convert nested list to list
3.Calculate the length of highest number. You can take 'n' on your choice as well. I took it as length of highest number
4.Convert all numbers as string
5.define function digits(). It initializes a list & append single digits according the index called
6.By looping over range(0,max_len/n), call digits() for each index:0-->n

Assuming you are using python do it as:
nestedArr = [[4,682,31249,81,523],[321741245,7],[349,25,5]]
for arr in nestedArr:
firstNums = [str(x)[0] for x in arr]
print(", ".join(firstNums))

Related

Python - Circular Shift Lists (but not the whole index)

so basically i want to make list shift left but only 1 digit from every index.
for example:
if i have this list [123,45678,90] i want to get this [234,56789,1]
another example just to make sure from this [12,34,56] i want to get this [23,45,61]
what ive done so far is
def main():
lst_lenght = int(input("Enter the lenght of the list:")) #amount of indexes
lst_elements = create_list(lst_lenght)
print(lst_elements)
def create_list(y):
lst = []
for i in range(y):
x = int(input('Enter the list elements:'))
lst.append(x)
return lst
then ive tried to do function that i will get the first digit of number(in every index)
after this i was just thinking removing the digit and placing it in the end of the index before it exept the first index which will go to the last one.
unfortunately i wasnt able to do it ive got stuck on this part, would love ur help, Thank you very much!!
You could do this with a list comprehension. Each element in the new list is defined by taking item[1:] (everything after the first digit in that item) plus next_item[0] (the first digit of the next item).
To do this, it's easier if you operate on it as a list of strings, and then convert back to integers to return.
def shifted_list(lst):
str_lst = [str(x) for x in lst]
str_lst_shifted_by_one = str_lst[1:] + [str_lst[0]]
shifted_str_lst = [item[1:] + next_item[0] for item, next_item in zip(str_lst, str_lst_shifted_by_one)]
return [int(x) for x in shifted_str_lst]
print(shifted_list([123,45678,90])) # [234, 56789, 1]

Python How to search through list X for element Y. Element Y is a list itself whose elements may not be in order as listed in X

I have a list:
X = ['rgb','rg870','rg1200','rg1550']
My second list is:
Y = [870,r,g]
I want to search in the X list and for the combination of Y list even if the order doesn't match and return the element index.
This should return index of 1. #At lest I think its position 1 as the first element is 0?
try this:
import numpy as np
X = ['rgb','rg870','rg1200','rg1550']
Y = ['870','r','g']
result = np.where([sorted(''.join(Y))==sorted(x) for x in X])[0]
print(result)
Code explanation:
''.join(Y) makes you move from a list Y to a string with all elements separated by an empty character.
sorted(''.join(Y)) orders your newly created string.
sorted(x) orders at the same way x, which is iteratively an element of X trhough list comprehension.
By comparing the sorted strings, you ensure that all the characters of Y are contained in the element x in the same number, even if original order was not the same.
Using np.where(_) searches for the position where the matching occurs. Since generally np.where is for matrices, you need to select the first element only: np.where(_)[0].
Finally you print your result which is a list of positions where the matching occurs. If you are sure that only one match occurs, then you may extract it simply doing result = np.where(_)[0][0], thus taking element 0 of your list of results.
# I have a list:
X = ['rgb','rg870','rg1200','rg1550']
# My second list is:
Y = ['870','r','g']
# I want to search in the X list and for the combination
# of Y list even if the order doesn't match and return the element index.
# This should return index of 1. #At lest I think its
# position 1 as the first element is 0?
# You don't mind if I use more descriptive variable names?
def find_combo(full_ids,segments):
for idx,full_id in enumerate(full_ids):
is_match = True
for segment in segments:
if segment in full_id:
pass
else:
is_match = False
break
if is_match:
return idx
else:
continue
find_combo(X,Y)
>>> 1

Adding string values together that are elements in a list

How would I go about doing the following? I need to add the number in the various elements together and assign the total to a new variable. I have been trying for days without much luck. I'm not sure if the numbers have to be split from the letters first?
list = ['2H','4B']
any help would be GREATLY appreciated.
edit:
Thanks for the replies eveyrone. I dont know why I cant get this right it seems like it should be so simple.
I will give you guys some more infomration.
the list below represents to playing cards, the first number or letter is the face value ie: 2 or 3 but can be a 'K' as well which stands for king and the value for that will be ten. the second part is the card suit ie. C for Clubs or H for hearts. I need to add the face value for these two cards together and get the hand total. a More accurate list might look like this.
list1 = ['KH', '10C']
Is this helping. it will help regardless of the number position in them element.
list1 = ['2H','4B']
list1=[word for x in list1 for word in x] #== Split the elements
print(list1)
new_var=0
for value in list1:
try:
value=int(value) #=== Convert to int
new_var+=value #== Add value
except ValueError:
pass
print(new_var)
One approach, using a list comprehension along with re.findall to extract the leading digits from each list entry:
list = ['2H','4B']
nums = [int(re.findall(r'^\d+', x)[0]) for x in list] # [2, 4]
output = sum(nums) # 6
You should avoid using function names as variable names i.e. list =
There are a few ways to do this and I suggest you review the Python documentation on slicing and indexing strings.
l = ['2H','4B']
result = sum(int(x[0]) for x in l)
print(result)
result equals sum of first char of each element of the list. I have converted each indexed element zero to integer to allow addition.
You can also do it the following way:
result = 0
for x in l:
result += int(x[0])
print(result)
You can extract numbers from each string then add them
You can use
total = 0
list = ['2H','4B']
for element in list:
res = [int(i) for i in element.split() if i.isdigit()]
total += sum(res)
print(total)

Finding the lowest number that does not occur at the end of a string, in a tuple in a list

I have a list of tuples, each has a single string as element 0, in these strings I want to get out the final number, and then find the lowest (positive) number that is not in this list.
How do you do this?
E.g. for the list tups:
tups=[('.p1.r1.c2',),('.p1.r1.c4',),('.p1.r1.c16',)]
the final numbers are 2, 4 and 16, so the lowest unused number is 1.
my attempt was this:
tups2= [tup[0] for tup in tups] # convert tuples in lists to the strings with information we are interested in
tups3 = [tup .rfind("c") for tup in tups2] # find the bit we care about
I wasn't sure how to finish it, or if it was fast/smart way to proceed
Where are you blocked? You can achieve that in basically two steps:
Step 1: Create the list of numbers
One way of doing this (inspired from there):
numbers = [int(s[0][len(s[0].rstrip('0123456789')):]) for s in tups]
In your example, numbers is [2, 4, 16].
Step 2: Find the lowest positive number that is not in this list
x = 1
while x in numbers:
x += 1
You didn't really specify your problem but I'm guessing that getting the lowest unused number is the issue.
the solutions above is great but it just gets the lowest number in the list and not the lowest unused one.
I tried to make a list of all the unused numbers then getting the minimum value of it.
I hope that would help
tups=[('15.p1.r1.c2',),('.poj1.r1.c4',),('.p2.r4.c160',)]
numbers = []
unused_numbers = []
for tup in tups:
words = tup[0].strip(".").split('.')
digits_list = [''.join(x for x in i if x.isdigit()) for i in words]
unused_numbers.extend(digits_list[:-1])
numbers.append(digits_list[-1])
print(numbers)
print(min(unused_numbers))
I used the same method Thibault D used to get a list of numbers:
tups=[('.p1.r1.c2',),('.p1.r1.c4',),('.p1.r1.c16',)]
num = [int(i[0][len(i[0].rstrip('0123456789')):]) for i in tups]
However, I used an easier method to get the minimum number:
min(num) - 1
This basically gets the lowest number in the list, and then subtracts 1 from it.

How to count the number of local maxima in a nested list?

I have a nested list of numbers. Like this one:
[[1,2,3],[3,2,1],[3,1,2],[2,3,1]]
Now, I want to count the number(s) that is bigger than it's previous element and it's front element, it must also has to have an element on both of it's sides. The output should be like this(inside a list):
[0,0,0,1]
The first element of the output list is zero because in the first nested list, it's first element has no other previous element but only 2 in it's front. For the second element(still on the first nested list) it has 1 as it's previous element and 3 as it's front one but the output is zero because it's needs to be greater than both the element in it's front and it's previous one. The third element is is also not valid because it doesn't have a front element, only it's previous one. The same is for the other nested lists except for the last one. In the last nested list 2 and 1 is already not valid, but 3 is, so now we need to check whether if this is higher than it's two elements. Since three is higher, we count +1 for the last nested list.
Another example:
[[1,2,1,3,1],[2,2,2],[2,3,4,3,4,2,3,1]]
The output should be:
[2,0,3]
The first element of the output list is 2 because in the first nested list(the first and last element is already invalid), 2 has both elements and it is also higher than the both. Then, we move on to 1, it also has both elements but it is smaller than the both so it's invalid. 3 is valid because it has both elements and it is also higher. So we count +2 since there are 2 numbers that valid. The second nested list is invalid because the number that has both elements cannot be equal to any of them, it needs to be higher, and the first and last element is already invalid.In the last nested list, the first and last element of it is already invalid, so we start from it's second one, 3, 3 has both elements but it is only higher than it's previous one but is smaller than it's front one. Next, 4 has both elements and it is also higher so it is counted. Next, 3 has both elements but it is smaller than both of them so it's not counted. Next, 4 has both elements and it is also higher than it's elements. Next, 2 has both elements but it is smaller than it's elements so it's not counted. Next, 3 has both elements and it is also higher than the both, so it's also count. Which makes the last element in the output list count +3.
I am sorry if the explanation is too long/lengthy, but is there any way of doing this in Python 3?
Edit:
So far, I have tried this:
listy = [[1,2,3],[3,2,1],[3,1,2],[2,3,1]]
list_hold = []
for x in listy:
for y in x:
if y>y+1 and y>y-1:
list_hold.append(x)
print(list_hold)
But it only return an empty list.
You need a sliding window iterator; something that produces 3 elements in a row from an input sequence; all you then have to do is count the number of such windows where the middle element is larger than the two other elements.
The sliding window problem is already solved: Rolling or sliding window iterator?, using the window() function from the top answer there would then give you:
def count_maxima(l):
# b, the middle value, is larger than both a and c
return sum(a < b > c for a, b, c in window(l, 3))
result = [count_maxima(sublist) for sublist in outerlist]
Demo:
>>> outerlist = [[1,2,3],[3,2,1],[3,1,2],[2,3,1]]
>>> [count_maxima(sublist) for sublist in outerlist]
[0, 0, 0, 1]
>>> outerlist = [[1,2,1,3,1],[2,2,2],[2,3,4,3,4,2,3,1]]
>>> [count_maxima(sublist) for sublist in outerlist]
[2, 0, 3]
My first thought would be to use np.diff. If you have a given list of values, vals, you can use np.diff(vals) to get an array that is negative if the next number is smaller, and positive if the next number is larger
def count_local_maxima(vals):
if len(vals) < 3:
return 0
diffs = np.diff(vals)
return np.sum((diffs[:-1]>0) & (diffs[1:]<0))
result = [count_local_maxima(sublist) for sublist in mainlist]

Categories

Resources