Alternate apporach for using a flag in python - python

What is the best/alternate pythonic way for the code below,
li=["Header",1,2,3,4,5]
l=0
for i in li:
if l == 0:
.....
l += 1
else:
....

You can replace:
l=0
for i in li:
if l ==0:
frobnosticate(i)
l+= 1
else:
twiddle(i)
With:
#do something with header outside the loop
frobnosticate(li[0])
#loop over everything but the first element
for i in li[1:]:
twiddle(i)

li=["Header",1,2,3,4,5]
do_stuff(li[0]) # first ....
for i in li[1:]:
normal_stuff(i) # second ...
This will deal with header first and then iterate through rest of list.

Accessing such pattern of elements using slicing is good enough. However, if data type in your list is not fixed/known, you may also use dictionary to redirect element to specified function:
def access_string_element(string):
....
def access_integer_element(integer):
....
access_table = dict()
access_table[str] = access_string_element
access_table[int] = access_integer_element
...
Then you could use the dict like this:
for element in li:
access_table[type(element)](element)
This way benefits if you are going to handle list containing data with different data type. It would make your loop looks clearer, and easy to manage.
Have Fun ;)

Related

Changing(replacing) a value in a list without using range(len())

My purpose is to change the value of the elements 3 and 4 to 4 and 3 and I have written a function that takes a list, first number and second number as arguments:
def pre9(the_list, value_to_replace, the_replacing_value):
for i in the_list:
if i == value_to_replace:
value_to_replace = the_replacing_value
elif i == the_replacing_value:
the_replacing_value = value_to_replace
return the_list
I then assign a test-case to a variabel and then print it:
test_pre9 = pre9([1,2,3,4,5,7,3,4], 3, 4)
print(test_pre9)
The result is: [1,2,3,4,5,7,3,4]
I expect it to be: [1,2,4,3,5,7,4,3]
I have for a long time ago written a code that accoplishes this task:
def uppgift_9():
the_list = [3,5,8,9,4,5]
for i in range(len(the_list)-1):
temp = the_list[3]
the_list[3] = the_list[4]
the_list[4] = temp
return the_list
But I've read in many places that using range(len()) is not "pythonic" and it is possible to do anything without using it.
Does anyone know why my code fails?
You don't actually change the item in the list, try this:
def pre9(the_list, value_to_replace, the_replacing_value):
for i, value in enumerate(the_list):
if value == value_to_replace:
the_list[i] = the_replacing_value
elif value == the_replacing_value:
the_list[i] = value_to_replace
return the_list
Now the list will have the actually items changed to what you wanted it to be. Enumerate() returns the index and value of an item in a list, it's very handy! And indeed, the range(len()) is not very pythonic and is usually used when people jump from other languages like Java, C# etc. Using enumerate() is the correct 'pythonic' way of achieving this.

I can't add input() in python list

`i = 0
while i < 5
i=i+1
li = []
li.insert(i,input('>>>'))
print(li)`
When I run this program. It only print last input by me.
Help please.
I want add all input in one by one...
Try this:
li = []
i = 0
while i < 5:
i=i+1
li.insert(i,input('>>>'))
print(li)
And if you want to store numbers as integer, try this:
li = []
i = 0
while i < 5:
i=i+1
li.insert(i,int(input('>>>')))
print(li)
Don't reset your list to an empty list [] on each loop.
Rather than controlling your index yourself, you can use a range.
Also, use append to append an item to your list.
So, your code could become:
li = []
for i in range(5):
li.append(input('>>>'))
print(li)
Use list comprehension for syntactic sugar. Also yeah to reiterate what others have said above, you reset the list on every iteration. Two, input() is a function that returns raw input(usually interpreted as string) so you need to either control its type return or use Regex to ensure you pull only specific answers(really constraining inputs is good practice). Finally when you iterate over a segment it could be easier to do so as a generator function for memory purposes- look into yield and generative functions.
newList = [int(input(‘>>>’)) for x in range(1,5)]
Print(newList)
See a single line could create the list you expected

Looping over a list and printing those elements of a string

So I need to create a function that iterates over a list of integers and print the characters of a string with those integers as indices. Something like this:
printString('123456789',[1,7,5,3])
2
8
6
4
i have this:
def printString(s,list):
i=0
resultString=str()
for i in range(len(list)):
resultString= s[list[i]]
i=i+1
print (resultString)
but it prints only the first character of the string, i guess there is a problem with the for-loop, i just can't find out what it is.
Any help will be useful! thank you
A function that results in this:
printString('123456789',[1,7,5,3])
2
8
6
4
Can be implemented in a multitude of ways, this is how i would do it.
def printString(input, indexArr):
for i in indexArr:
print(input[i])
printString('123456789',[1,7,5,3])
Live Demo
Move print(resultString) so that it's inside the loop.
def printString(s,list):
i=0
resultString=str()
for i in range(len(list)):
resultString= s[list[i]]
i=i+1
print (resultString)
Additional but non-essential advice:
You don't need i=0 or i=i+1, since the for loop already does the work of creating and incrementing the value for you.
def printString(s,list):
resultString=str()
for i in range(len(list)):
resultString= s[list[i]]
print (resultString)
You don't need resultString=str() because Python is perfectly happy to create a new variable in the middle of a function without any hints as to what its type should be.
def printString(s,list):
for i in range(len(list)):
resultString= s[list[i]]
print (resultString)
You don't necessarily need resultString at all since you're only using its value once.
def printString(s,list):
for i in range(len(list)):
print (s[list[i]])
It's preferable to iterate over the elements of a list rather than its indices, if you don't have a specific need for the index.
def printString(s,list):
for idx in list:
print (s[idx])
Try not to use variable names that are identical to the names of built-in types.
def printString(s,seq):
for idx in seq:
print (s[idx])
It's because you are not appending all the result into the string, this will give you answer: 2864
def printString(s,list):
i=0
resultString=str()
for i in range(len(list)):
resultString+=s[list[i]]
i=i+1
print (resultString)
printString('123456789',[1,7,5,3])
There are several problems here. First, the print statement should be indented inside the loop. Second, even though it's innocuous here, you shouldn't manipulate i yourself, but leave the for loop to do it for you. And last, list is a horrible name for a variable, as it hides python's built-in list. Bring it all together, and you'd get something like this:
def printString(s, lst):
for i in range(len(lst)):
resultString = s[lst[i]]
print (resultString)
Given your args as a test case:
#!/usr/bin/python
def printString(strng, indexes):
return ''.join((c for i,c in enumerate(strng) if i in indexes))
This uses enumerate() and a generator.
You just need to put the print statement inside the for loop. It is only printing the last element because it gets overridden each time. You can also simply it as well
def printString(s,list):
resultString=str()
for i in range(len(list)):
resultString= s[list[i]]
print (resultString)

Getting value from a list corresponding to another list

I have a list containing:
NewL = [(1.1,[01,02]),(1.2,[03,04]),(1.3,[05,06])]
and i used enumerate to obtain the list as above where the square brackets containing [01,02],[03,04] and [05,06] are generally obtained from another list. I'll show it just in case:
L = [[01,02],[03,04],[05,06]]
and initially the output list is just:
OutputList = [1.1,1.2,1.3]
i used enumerate on both of this list to get what i have as the first list i've written above.
The problem i'm facing now is, let's say i want to only output the value for [05,06] which is 1.3 from the NewL. How would i do that? I was thinking of something like:
for val in NewL:
if NewL[1] == [05,06]:
print NewL[0]
but it's totally wrong as cases might change where it's not necessary always be [05,06] as it can be obtaining value for [03,04] and [01,02] too. I'm pretty new using enumerate so I'll appreciate any help for this.
The for loop should like this:
for val in NewL:
if val[1] == [5,6]:
print val[0]
It will print 1.3
I'm not sure I understand the question, so I will extrapolate what you need:
Given your 2 intial lists:
L = [[01,02],[03,04],[05,06]]
OutputList = [1.1,1.2,1.3]
you can generate your transformed list using:
NewL = list(zip(OutputList, L))
then, given 1 item from L, if you want to retrieve the value from OutputList:
val = [x for x, y in NewL if y == [05,06]][0]
But it would be a lot easier to just do:
val = OutputList[L.index([05,06])]
Note that both those expressions will raise an IndexError if the searched item is not found

Why am I only getting one item from list

I am trying to get shared letters from a string compared to a list of letters. I only return the last letter of l that shares with w . I want all the shared letters instead.
def f(w,l):
common = []
for i in w:
if in i in l:
return common.append(i)
As soon as i is in l your code returns, which immediately exits your function. instead do this:
def f(w,l):
common = []
for i in w:
if i in l:
common.append(i) # no return needed so it will collect all
return common
Make sure you return common at the end your function so you get all the values stored in common.
try this:
def f(w,l):
common = []
for i in w:
if i in l:
common.append(i)
return common
The problem is that the .append method of a list returns None. You were returning from the function the first time you did .append, so you were always going to return None from the function.
I think that what you are really looking for is a list comprehension:
def f(w,l):
return [i for i in w if i in l]
As others have pointed out, you might want to choose more descriptive variable names.

Categories

Resources