Values in a list to a range() - python-3.x

I have a user input which comes in as follows:
j = ['1', '2', '3', '4', '5-6', '7-9']
I want to go through this list, identify any 'ranges' such as 7-8, or 5-99 etc.
With these remove the - and put the first and second values into range()
So far I have the following, I just can't figure out how to get the values into the right place, perhaps I need to select the number before the - and after the - ?
for item in j:
if "-" in item:
item = item.split("-")
# list(map(str, range(244, 247)))
for r in item:
print(r)
print('next')
# something like this?
list(map(str, range(int(item[0]), int(item[1]))))
EDIT
Taking into account jonrsharpe's comment:
for item in j:
if "-" in item:
start, stop = item.split("-")
print('start:' + start + ' end: ' + stop)
list(map(str, range(int(start), int(stop))))
This returns a type error TypeError: 'str' object is not callable

Assuming the output expected is j = [1, 2, 3, 4, 5, 6, 7, 8, 9]
You can create a blank list, process each element depending on whether or not it has a "-"
l = ['1', '2', '3', '4', '5-6', '7-9']
ll = []
for element in l:
if '-' in element:
sublist = element.strip().split('-')
sublist = list(range(int(sublist[0]), int(sublist[1]) + 1))
ll += sublist
else:
ll.append(int(element))

One approach is to create a list of items for both single numbers and ranges, and then use this as the argument to range:
j = ['1', '2', '3', '4', '5-6', '7-9']
for item in j:
if '-' in item:
rng = [int(x) for x in item.split('-')]
else:
# Start and stop are the same
rng = [int(item)] * 2
# Pad the stop number
rng[1] += 1
for i in range(*rng):
print(i)

Related

Converting string into list of every two numbers in string

A string = 1 2 3 4
Program should return = [[1,2],[3,4]]
in python
I want the string to be converted into a list of every two element from string
You could go for something very simple such as:
s = "10 2 3 4 5 6 7 8"
l = []
i = 0
list_split_str = s.split() # splitting the string according to spaces
while i < len(s) - 1:
l.append([s[i], s[i + 1]])
i += 2
This should output:
[['10', '2'], ['3', '4'], ['5', '6'], ['7', '8']]
You could also do something a little more complex like this in a two-liner:
list_split = s.split() # stripping spaces from the string
l = [[a, b] for a, b in zip(list_split[0::2], list_split[1::2])]
The slice here means that the first list starts at index zero and has a step of two and so is equal to [10, 3, 5, ...]. The second means it starts at index 1 and has a step of two and so is equal to [2, 4, 6, ...]. So we iterate over the first list for the values of a and the second for those of b.
zip returns a list of tuples of the elements of each list. In this case, [('10', '2'), ('3', '4'), ('5', '6'), ...]. It allows us to group the elements of the lists two by two and iterate over them as such.
This also works on lists with odd lengths.
For example, with s = "10 2 3 4 5 6 7 ", the above code would output:
[['10', '2'], ['3', '4'], ['5', '6']]
disregarding the 7 since it doesn't have a buddy.
here is the solution if the numbers exact length is divisible by 2
def every_two_number(number_string):
num = number_string.split(' ')
templist = []
if len(num) % 2 == 0:
for i in range(0,len(num),2):
templist.append([int(num[i]),int(num[i+1])])
return templist
print(every_two_number('1 2 3 4'))
you can remove the if condition and enclosed the code in try and except if you want your string to still be convert even if the number of your list is not divisible by 2
def every_two_number(number_string):
num = number_string.split(' ')
templist = []
try:
for i in range(0,len(num),2):
templist.append([int(num[i]),int(num[i+1])])
except:
pass
return templist
print(every_two_number('1 2 3 4 5'))

Python 3.6 - How to search through a 2D list and return true or false if an item matches user input

I am using EDX to start learning python and I am stuck in a project that requires me to create a tic tac toe game.
I believe I have managed to complete most of the functions but when I tried to run the function that checks whether a position is available to be marked as X or O, I always get a false reading. It returns true only for the 7 and not for the rest of the items.
board = [['7', '8', '9'], ['4', '5', '6'], ['1', '2', '3']]
location = input(" Turn, select a number (1, 9): ")
def available(location, board):
for row in board:
for col in row:
if col==location:
return True
else:
return False
print(available(location,board))
I decided to separate the function from the rest of the code. The code above should be able to search the 2D list and if it finds the number that the user has entered to return true or false. When it does that another function is executed to change that number to X or O depending the player. I tried to run the function without the function and with print instead of return and works fine.
board = [['7', '8', '9'], ['4', '5', '6'], ['1', '2', '3']]
location = input(" Turn, select a number (1, 9): ")
for row in board:
for col in row:
if col==location:
print("True")
else:
print("False")
Any idea what I am doing wrong?
Let's look at your if else statement.
When the input number is not 7, we do not return true, instead we go to the else and immediately return false without checking the rest of the numbers.
The solution is to remove the else, and just return false only after iterating through every cell.
When you change the returns to prints this bug disappears because you are no longer returning, and therefore execution doesn't stop early.
def available(location, board):
for row in board:
for col in row:
if col==location:
return True
return False
The key insight here is that returning from a function, exits the function.
To overcome the problem you identified, you could for instance flatten your list by using a list comprehension and check for the existence of location in it:
board = [['7', '8', '9'], ['4', '5', '6'], ['1', '2', '3']]
location = input(" Turn, select a number (1, 9): ")
def available(location, board):
#collect all elements from all sublists in a list
allfields = [i for j in board for i in j]
#location element of this list?
if location in allfields:
return True
return False
print(available(location,board))
You can use any for a more Pythonic version.
def available(location, board):
return any(any(i == location for i in row) for row in board)

Using python need to get the substrings

Q)After executing the code Need to print the values [1, 12, 123, 2, 23, 3, 13], but iam getting [1, 12, 123, 2, 23, 3]. I have missing the letter 13. can any one tell me the reason to overcome that error?
def get_all_substrings(string):
length = len(string)
list = []
for i in range(length):
for j in range(i,length):
list.append(string[i:j+1])
return list
values = get_all_substrings('123')
results = list(map(int, values))
print(results)
count = 0
for i in results:
if i > 1 :
if (i % 2) != 0:
count += 1
print(count)
Pretty straight forward issue in your nested for loops within get_all_substrings(), lets walk it!
You are iterating over each element of your string 123:
for i in range(length) # we know length to be 3, so range is 0, 1, 2
You then iterate each subsequent element from the current i:
for j in range(i,length)
Finally you append a string from position i to j+1 using the slice operator:
list.append(string[i:j+1])
But what exactly is happening? Well we can step through further!
The first value of i is 0, so lets skip the first for, go to the second:
for j in range(0, 3): # i.e. the whole string!
# you would eventually execute all of the following
list.append(string[0:0 + 1]) # '1'
list.append(string[0:1 + 1]) # '12'
list.append(string[0:2 + 1]) # '123'
# but wait...were is '13'???? (this is your hint!)
The next value of i is 1:
for j in range(1, 3):
# you would eventually execute all of the following
list.append(string[1:1 + 1]) # '2'
list.append(string[1:2 + 1]) # '23'
# notice how we are only grabbing values of position i or more?
Finally you get to i is 2:
for j in range(2, 3): # i.e. the whole string!
# you would eventually execute all of the following
list.append(string[2:2 + 1]) # '3'
I've shown you what is happening (as you've asked in your question), I leave it to you to devise your own solution. A couple notes:
You need to look at all index combinations from position i
Dont name objects by their type (i.e. dont name a list object list)
I would try something like this using itertools and powerset() recipe
from itertools import chain, combinations
def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))
output = list(map(''.join, powerset('123')))
output.pop(0)
Here is another option, using combinations
from itertools import combinations
def get_sub_ints(raw):
return [''.join(sub) for i in range(1, len(raw) + 1) for sub in combinations(raw, i)]
if __name__ == '__main__':
print(get_sub_ints('123'))
>>> ['1', '2', '3', '12', '13', '23', '123']

Python - match dictionary value within string & print key in string order

I asked a similar question to this earlier on but Im still having a hard time figuring this out. I have the following code:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '401'}
string = '401203010'
text = ''
for i, j in d.items():
if j in string:
text += i
print(text) #prints karp
desired output: park
the output I get is karp, however I would like the output to be in order of value match in the string, Thanks!
try this maybe?
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
keylen = len(''.join(d.keys()))
while len(text) != keylen:
found_val = 0
for i, j in d.items():
jl = len(j)
if string[:jl] == j:
text += i
string = string[jl:]
found_val += 1
if found_val == 0:
break
print(text)
for the sake of clarity, this is really not an algorithm you want to use here. For example one of the downfalls is if it isn't guaranteed that a part of the string will be in the dictionary values then the loop will never end. I don't want to spend the mental resources to fix that potential pitfall because I have some reading to do but perhaps you can figure out a way around it.
edit, never mind that wasn't that difficult but you should test various edge cases.
You could first split up string into substrings of 2, and then switch the keys ad values of d in a temporary dictionary, then just add the values from that:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
split_string = [string[i:i+2] for i in range(0, len(string), 2)]
# ['40', '20', '30', '10']
new_dict = dict((y,x) for x,y in d.items())
# {'30': 'r', '10': 'k', '20': 'a', '40': 'p'}
text = "".join(new_dict[string] for string in split_string)
print(text)
# park

List containing lists (matrix) as input() with python 3

I'm trying to convert a given input to a list containing lists as shown in the command-line code below:
matrix = input('asking')
asking[[2, 0, 4],[1, 2, 4],[4, 4, 2]]
matrix
'[[2, 0, 4],[1, 2, 4],[4, 4, 2]]'
desired output:
[[2,0,4],[1,2,4],[4,4,2]]
Attempts
list(matrix)
['[', '[', '2', ',', ' ', '0', ',', ' ', '4', ']', ',', ' ', '[', '1', ',', ' ', '2', ',', ' ', '4', ']', ',', ' ', '[', '4', ',', ' ', '4', ',', ' ', '2', ']', ']']
x = [int(a) for a in matrix]
builtins.TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
matrix.split(',')
['[[2', '0', '4]', '[1', '2', '4]', '[4', '4', '2]]']
Code:
fin_result = 0
def perform_check():
print("Enter form \n [[a,b,c] \n [d,e,f] \n [g,h,i]]")
#ask_for_input = [[4,-1,1],[4,5,3],[-2,0,0]]
ask_for_input = [[2,0,4],[1,2,4],[4,4,2]]
print(type(ask_for_input))
#call function to cont
calculate_determinate_matrix(ask_for_input)
def calculate_determinate_matrix(matrix3x3):
matrix_list2x2 = []
matrix_list2x2.append([[matrix3x3[1][1], matrix3x3[1][2]], [matrix3x3[2][1], matrix3x3[2][2]]])
matrix_list2x2.append([[matrix3x3[1][0], matrix3x3[1][2]],[matrix3x3[2][0], matrix3x3[2][2]]])
matrix_list2x2.append([[matrix3x3[1][0], matrix3x3[1][1]],[matrix3x3[2][0], matrix3x3[2][1]]])
count = 0
for count, matrix_2x2 in enumerate(matrix_list2x2):
if count % 2 == 1:
calculate_2x2_matrix(matrix_2x2, matrix3x3[0][count] * -1)
else:
calculate_2x2_matrix(matrix_2x2, matrix3x3[0][count])
def calculate_2x2_matrix(matrix, mult):
global fin_result
result = matrix[0][0] * matrix[1][1]
result_2 = matrix[0][1] * matrix[1][0]
fin_result += mult * (result - result_2)
def main():
perform_check()
print(fin_result)
if __name__ == "__main__":
main()
Clearly this code needs work, but I can't figure this in terms of list comprehension.
Use json loads() method:
matrix = '[[2, 0, 4],[1, 2, 4],[4, 4, 2]]'
matrix = json.loads(matrix)
type(matrix)
<type 'list'>
And in case you want to check for errors in input you can wrap it in try-except:
try:
matrix = json.loads(matrix)
except ValueError:
#code goes here
An alternative to json.loads is ast.literal_eval. It has the advantage that it recognizes Python syntax even if it was invalid JSON, like single-quoted strings. In your exact case, it doesn't make a difference:
import ast
matrix = '[[2, 0, 4],[1, 2, 4],[4, 4, 2]]'
matrix = ast.literal_eval(matrix)

Resources