I am trying to write a function which outputs all possible combinations of char list with length and without any repeats like aa, bb etc.
I am now on this stage:
def sequences(char_list, n, lst = []):
if len(lst) == n:
print(lst)
else:
for i in range(len(char_list)):
temp_list = [char_list[j] for j in range(len(char_list)) if i != j]
sequences(temp_list, n, lst + [char_list[i]])
print(sequences(["a", "b", "c"], 2))
Output is correct but I have None at the end. I actually have no idea why.
['a', 'b']
['a', 'c']
['b', 'a']
['b', 'c']
['c', 'a']
['c', 'b']
None
And what is the best way to get strings in the output and not lists?
The function sequences doesn't return anything (there's no return statement anywhere in the code), so it'll automatically return None. print(sequences(["a", "b", "c"], 2)) will execute this function and print its return value, outputting None.
To get strings instead of lists, concatenate all the strings in the list like this:
print(''.join(lst))
Every function has an implicit return None at the end of it. On the last line of your code, you asked Python the print the output of sequences, which is None since no return value was specified.
Well the problem was is that I printed it at the end once again.
Related
Most solutions to checking for a value in a list are just general checks, like if "a" is anywhere in the list return true. If the list is
['a', 'b', 'c']
I want to see if "a" is in the first slot. I'm pretty new to python, so I'm not sure how complicated the solution is going to be.
To see if 'a' is in the the first slot, you simply write:
list = ['a', 'b', 'c']
if list[0] == 'a':
print('yes')
If you wanted to find the index number, the code is:
list = ['a', 'b', 'c']
for i in list:
if i == 'a':
print('index: %s' % list.index(i))
This will tell you the index number, however if you wanted the slot number, you change list.index(i) to int(list.index(i) + 1) and %s to %d.
I don't understand recursive part.
def length(list1):
if list1 == [] or list1 == "":
return 0
else:
return 1+length(list1[1:])
a = [1,2,3,4,5]
print "Length of list is: ",length(a)
This is code. and that code's role is like len function.
and output is for a; 5
but return 1+length(list1[1:]) that part is not understandable for me.
why there is "1"? and why it starts with 1? why not "0"?
I thought length(list1[0:]) but it doesn't run.
actually i think but, ı understand nothing about that part.
can anyone explain?
The length of a list can be defined recursively as:
0 if the list is empty (equal to the empty list [])
1 + the length of the list deprived of its first element. (e.g. if you have a list with 3 elements, the length is the same as 1 + the length of the same list without one of its element (2))
Here, list1[1:] is a new list similar to list1 but without the first element.
If we take a concrete example with the list ['a', 'b', 'c']:
['a', 'b', 'c'] is different than the empty list [], then we return 1 + length(['b', 'c']). ['b', 'c'] is different than the empty list [], then length(['b', 'c']) returns 1 + length(['c']); and so on until length([]) is called.
In python: a[1:] means "take all values of a starting from 1, so excluding 0", for instance:
"abc"[1:] == "bc"
[2, 3, 4][1:] == [3, 4]
The function you are looking at takes either a list or a string, then remove an item and counts the remaining until it find an empty one, in this case returns its length (0).
The function satisfiesF() takes a list L of strings as a paramenter. function f takes a string as a parameter returns true or false. Function satisfiesF() modifies L to contain only those strings,s for which f(s) returns true.
I have two different programs aimed to produce the same output. But I am getting different outputs.
First program:
def f(s):
return 'a' in s
def satisfiesF(L):
k=[]
for i in L:
if f(i)==True:
k.append(i)
L=k
print L
print
return len(L)
L = ['a', 'b', 'a']
print satisfiesF(L)
print L
Output:
['a', 'a']
2
['a', 'b', 'a']
Second program:
def f(s):
return 'a' in s
def satisfiesF(L):
for i in L:
if f(i)==False:
L.remove(i)
print L
print
return len(L)
L = ['a', 'b', 'a']
print satisfiesF(L)
print L
output:
['a', 'a']
2
['a', 'a']
Please explain why these are giving differnt outputs.
In your second function you are seeing 2 as the length and all the elements in L outside the function because you are setting a local variableL which is a reference to k, your L created outside the function is not affected. To see the change in L you would need to use L[:] = k, then printing L will give you ['a', 'a'] outside the function as you are changing the original list object L list passed in to the function.
In the first you are directly modifying L so you see the changes in L outside the function.
Also never iterate over a list you are removing element from, if you make
L = ['a', 'b', 'a','a','d','e','a'], you will get behaviour you won't expect. Either make a copy for i in L[:] or use reversed for i in reversed(L):
In the first function, you assign over L in satisfiesF(), but you never modify the original list. When you write L=k, that makes the reference L now refer to the same list as k. It doesn't assign to the original list.
In contrast, in the second function you modify L without reassigning to it.
Also, as a side note, you shouldn't modify a list while you iterate over it.
As a second side note, you can rewrite satisfiesF as a one-liner:
L = [item for item in L if f(item)]
This was down voted mistakenly. The question was changed. So, the answer got outdated. Following is the answer for changed question:
L=k
Above would mean that we lost the reference to L.
So, Try this:
To the 1st program, comment the above assignment, do below, to retain reference to L:
# L=k
del L[:]
L[:] = k
Now both programs will output same, below one:
['a', 'a']
2
['a', 'a']
Best of luck.
In the question, there are two Ls. A global one and a local one. The
print L
statement prints the GLOBAL L, which you did not mutate in the programme.
Therefore, in order to let the programme knows that you want to mutate the global L, instead of the local L, you can add the line
globals()['L'] = L
to your first programme. I hope this can help!
In the first program, if you want to mutate the original list L and see the change made by your function, you should replace L = K in your code with L[:] = k:
def satisfiesF(L):
k=[]
for i in L:
if f(i)==True:
k.append(i)
# new code --------
L[:] = k # before: L = K
# -----------------
print L
print
return len(L)
This will give you ['a', 'a'] outside the function.
About mutating a list within a loop in the second program...
Just to remember that during a "for" loop, python keeps track of where it is in the list using an internal counter that is incremented at the end of each iteration.
When the value of the counter reaches the current length of the list, the loop terminates. This means that if you are mutating the list within the loop you can have surprising consequence.
For example, look at the for loop below:
my_list = ['a', 'b', 'c', 'd']
>>>print "my_list - before loop: ", my_list
my_list - before loop: ['a', 'b', 'c', 'd']
for char in my_list:
if char == 'a' or char == 'b':
my_list.remove(char)
>>>print "my_list - after loop: ", my_list
my_list - after loop: ['b', 'c', 'd']
Here, the hidden counter starts out at the index 0, discovers that "a" (in my_list[0]) is in the list, and remove it, reducing the length of my_list to 3 (from the initial 4). The counter is then incremented to 1, and the code proceeds to check the "if" condition, at the position my_list[1], in the mutated list (now of len == 3). This means that you will skip the "b" character (present now at the index 0) even if it had to be remove it.
One solution for this is to use slicing to clone and create a new list where you can remove items from it:
cloneList = my_list[:]
I've been given the assignment as follows:
Write a function called insert that takes 3 parameters, listA, listB and an index, then returns a copy of listA with the elements of listB inserted at the index. Your code should work with both strings and lists.
examples should look give this:
insert([1,2,3], ['a', 'b', 'c'], 3) should give [1, 2, 'a', 'b', 'c', 3]
AND:
insert('dog', 'cat', 1) should give 'dcatog'
I want to complete this first part both with and without loops. So far I have gotten:
def insert (listA, listB, index):
return listA[0:index] + listB + listA[index:len(listA)]
and this works out correctly, giving the correct example shown above. I don't know how to do this with loops, though. I've been trying to use for loops as follows:
def insert (listA, listB, index):
for nextchar in listA:
if nextchar == index:
listA.insert(index, listB)
return listA
but that's not correct. It's the closest I've gotten though, giving
[1, 2, ['a', 'b', 'c'], 3]
AND
'dog'
for the examples above.
but that's a nested list, yes? I don't want that. and the second example is completely wrong.
For the "dog" example, remember that strings in Python are immutable... that is, they can't be changed. So if you are trying to insert some characters into a string "dog", it won't be changed.
Strings don't have the "insert" method at all, so you will get an error in the "dog" example.
You will need to create a new string, and NOT use the insert method, if it's a string being passed in.
Your example is a bit off I believe.
insert([1,2,3], ['a', 'b', 'c'], 3)
should in fact return
[1, 2, 3, 'a', 'b', 'c']
Anyhow, here's my fix:
def insert (listA, listB, index):
if index == len(listA):
listA.extend(listB)
return listA
for i in range(len(listA)):
print i
if i == index:
for j, b_elem in enumerate(listB):
listA.insert(i+j, b_elem)
return listA
A bug with your given code is that you are inserting a list into that index of listA, as opposed to inserting each element of listB STARTING from that index.
Hey guys I need help on this past test question. Basically I am given two list of objects, and I am suppose to find the number of items that appear in the same position of the first list and the second. I have an example that was provided.
>>> commons(['a', 'b', 'c', 'd'], ['a', 'x', 'b', 'd'])
2
>>> commons(['a', 'b', 'c', 'd', 'e'], ['a', 'x', 'b', 'd'])
2
I am having trouble writing out the code. Our class is using python 3. I have no idea where to start writing this from. It is a first year programming course and I never did programming in my life.
I think a more straightforward solution would be:
def commons(L1,L2):
return len([x for x in zip(L1,L2) if x[0]==x[1]])
This is not a simple problem for a beginner. A more straightforward approach would use functions like sum and zip with a list comprehension like so:
def commons(L1, L2):
return sum(el1 == el2 * 1 for el1, el2 in zip(L1, L2))
A more typical but error prone approach taken by beginners is:
def commons(L1, L2):
count = 0
for i, elem in enumerate(L2):
if elem == L1[i]:
count += 1
return count
I say this is more error prone because there are more parts to get right.
Without using enumerate you could do:
def commons(L1, L2):
count = 0
for i, range(len(L2)):
if L1[i] == L2[i]:
count += 1
return count
but these previous two will work only if len(L2) <= len(L1). See what I mean by more error prone? To fix this you would need to do:
def commons(L1, L2):
count = 0
for i, range(min(len(L2), len(L1))):
if L1[i] == L2[i]:
count += 1
return count
Seems like this would work:
def commons(l1, l2):
return sum(1 for v1,v2 in map(None, l1,l2) if v1 == v2)
Note: The degenerate form of map used here results in None being returned for all values in the shorter list (so even if l1 and l2 are not the same length, it'll work.) It assumes that both lists all have values (i.e., L1 and L2 do not contain None - since that would end up in false positives if one list was shorter than the other.)