Function that prints each element of a list and its index per line - python-3.x

I am trying to write a function that can print the element and index of a list. I want to do this without using the enumerate built in function and do it using for loops.
I was able to print out the element but I couldn't figure out a way to loop the index of my list.
Is there any good way I could work around this? Many thanks.

You could do this, simply iterating over the range of numbers regarding the length of your list:
def item_and_index(my_list):
for i in range(len(my_list)):
print(my_list[i], i)
This is exactly what you need, a function using for loops and not the enumerate function.

>>> L = ['a', 'b', 'c']
>>> for i in range(len(L)):
... print(i, L[i])
...
0 a
1 b
2 c
You could also try this:
i = 0
for elem in L:
print(i, elem)
i += 1

Related

Creating a dictionary from list of lists using only one for loop

I came across this question in a test. There are two parts to this question:
Part i:
Given a list of flavors, eg. ['A','A','A','A','B','B','B','B','B','C','C','C','C'], write a function that returns a dictionary of the number of each flavor respectively.
My solution:
flavors = ['A','A','A','A','B','B','B','B','B','C','C','C','C']
def count_flavors(l):
dict_flavors={}
for i in l:
dict_flavors[i] = l.count(i)
return dict_flavors
print(count_flavors(flavors))
Part ii:
Using not more than ONE for loop write a function that accepts a list of lists of flavors eg. [['A', 'A', 'B', 'B', 'B', 'C', 'C'], ['A', 'A', 'B', 'B', 'B', 'B', 'C'], ['A', 'B', 'C', 'C']] and returns a dictionary for the total number of each flavor. You must include the function that you defined in part one in this solution.
(To clarify, essentially there should only be two for loops; one from part one and one from part two)
So far my solution is the following:
batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']]
def batch_count(b):
batch_dict = []
result = {}
for j in b:
batch_dict.append(count_flavors(j))
print(batch_dict)
for i in batch_dict:
for k in i.keys():
result[k] = result.get(k,0) + i[k]
return result
print('batch count 1:' + str(batch_count(batches)))
I am struggling to find a solution that only uses one for loop for this part. I am aware that there are modules that exist for this sort of thing like collections.Counter(). Is a naive solution that does not include any modules possible for this problem?
Thanks!
Here is the best naive solution which I can think of in order to achieve what you want
Benefits of using the solution
No need to create extra variable like batch_dict = [], which takes unnecessary space in your system
No need to carry out multiple computations using different methods, like you did above using count_flavors()
Straight forward and easy to understand
FINAL SOLUTION
batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']]
def batch_count(b):
result = {} # for storing final count results
# two loops are required to get into the arrays of array, not other option is there
for items in b:
# Getting the nested array item here
for item in items:
# final computation, if the item is there in the result dict, then increment
# else simply assign 1 to the item as a key which eventually gives you the total number
# of counts of each item throughout the batches array items
if item in result:
result[item] += 1
else:
result[item] = 1
return result
print('batch count 1:' + str(batch_count(batches)))
# OUTPUT
# >>> batch count 1:{'A': 7, 'C': 7, 'B': 10}
Feel free to test this out for some other batches too, and let me know. This is by far the naive solution which is possible to give out what you want to achieve. Keep learning :)
ANOTHER SOLUTION [MAKING USE OF FIRST METHOD COUNT_FLAVORS]
Hey, if you really want to use the first method, then there is a work around, but you need to compromise with one thing now, that is Counter has to be imported, but I assure you, it will be as simple as that, and will give you straight forward answer
Your count_flavors works fine, so we take the count_falvors() as is.
We will be making changes to the batch_count method now
FINAL SOLUTION
from collections import Counter
# Taking your method as is, to get the dictionary which counts
# the items occurence from your array
def count_flavors(l):
dict_flavors={}
for i in l:
dict_flavors[i] = l.count(i)
return dict_flavors
# This method will do your stuffs
def batch_count(b):
result = {} #this will be used to return the final result
# now just one loop, since we will passing the array
# to our method for computation count_flavors()
for items in b: # this will give out single array
'''
now we will call your count_flavor method
we will use Counter() to merge the dictionary data
coming from the count_flavor and then add it to the result
Counter() keep track of same item, if present in multiple
dict, ADDS +1 to the same item, doesn't duplicate value
Hence counter required
'''
if len(result) != 0:
# if the result is not empty, then result = result + data
result += Counter(count_flavors(items)) # no more extra for loop
else:
# else first fill the data by assigning it
result = Counter(count_flavors(items))
# this will give out the output in {}
# else the output will come in Counter({}) format
return dict(result)
# our test array of arrays
batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']]
print('batch count 1:' + str(batch_count(batches)))
# OUTPUT
# >>> batch count 1:{'A': 7, 'B': 10, 'C': 7}
In this way you achieve the output with the usage of your count_flavors() method too, that too with no multiple loops in the batch_count(). Hope that will give you more clarity :). If this works out for you, you may accept the answer, for the the people who will come looking for answer to this question :)
The first function can become much faster by modifying your approach in this way:
def count_flavors(lst):
dict_flavors = {}
for item in lst:
if item in dict_flavors:
dict_flavors[item] += 1
else:
dict_flavors[item] = 1
return dict_flavors
You could also use Counter to simplify your code:
from collections import Counter
def count_flavors(lst):
return dict(Counter(lst))
The second function can use itertools.chain:
from collections import Counter
from itertools import chain
def batch_count(b):
return dict(Counter(chain(*b)))

TypeError: list indices must be integers or slices, not str. While selecting item from loop for

I´ve been trying for a while to select an item from a list with the variable of the for loop. But I keep getting this error:
TypeError: list indices must be integers or slices, not str
The issue dissapears when I change the i for a number, but that's not what I want to do. I´ve been looking for similar issues but couldn't manage to get it working. Advise please.
I want this to result as: ['p1', 'q1', 'p2', 'q2', 'p3', 'q3', 'p4', 'q4', 'p5', 'q5']
listcont=[]
cont=0
while cont<=5:
for i in list:
listcont.append(list[i]+str(cont))
cont+=1
return listcont
n=5
list=['q','p']
print(concat(list,n))´´´
First, when you write for i in list you're already iterating over the elements of the list, not the indices. So you can use the item directly:
listcont.append(i + str(cont))
Second, you shouldn't name things list since it shadows the built-in of that name and will cause all kinds of trouble.
Third, the while loop would be better written as a for with a range
n = 5
my_list = ['q', 'p']
listcont = []
for counter in range(1, n+1):
for item in my_list:
listcont.append(item + str(counter))
Finally, you can simplify all of this into a list comprehension and make it look neater with an f-string:
def make_list(my_list, limit):
return [f'{item}{counter}' for counter in range(1, limit+1) for item in my_list]
make_list(['p', 'q'], 5)
When you use for loop, you must know that if you are using for i in list it means that i here is the element of the list, and the loop will traverse each element of the list.
While, what you want to do is for i in range(len(list)), this will traverse the list with i as a number which can gain a value, less than or equal to len(list) - 1.
You can learn this very basic thing about for loop here and hold yourself back from asking such questions.
Hope it helps, thanks.
You have a variable called list which is a bad idea because list is the type of a list in Python. But this isn't the issue. I'm guessing the function you have there, which is missing the declaration, is the function def concat(list, n), and you intended to write while cont <= n.
If all this is the case, when you do
for i in list:
i is going to be members of the list, so 'q', then 'p'. In this case list['p'] doesn't make any sense.
To get the output you're going for I would do (to be easy to read):
def concat(lst, n):
result = []
for i in range(n):
for v in lst:
result.append('{}{}'.format(v, i+1))
return result
You could do the whole thing in one line with:
['{}{}'.format(value, count + 1) for count in range(n) for value in lst]

Why is sorted() not sorting my list of strings?

Problem:
So I was trying to alphabetically sort my list of strings maybe I overlooked something very minor. I have tried both .sort and sorted() but maybe I didn't do it correctly?
Here is my Code:
words = input("Words: ")
list1 = []
list1.append(words.split())
print(sorted(list1))
Expected output-
Input: "a b d c"
Output: ['a', 'b', 'c', 'd']
Current output-
Input: "a b d c"
Output: [['a', 'b', 'd', 'c']]
Your code is not working because you are trying to sort a list inside a list.
When you call words.split() it returns a list. So when you do list1.append(words.split()) it is appending a list into list1.
You should do this:
words = input("Words: ")
list1 = words.split()
print(sorted(list1))
You can try a simple method as follows:
list1 = [i for i in input('Words: ').split(' ')]
print(sorted(list1))
I've tested it. And it is working
Without deviating from your current effort, the only modification you need to do to fix your code is :
words = input("Words: ")
list1 = []
list1.append(words.split())
print(sorted(list1[0]))
Explanation of what you were doing wrong:
The root cause of your confusion is append() .According to python docs,append() takes exactly one argument.
So when you do this,
words.split()
You are trying to append more than 1 element into the list1 and when you append() something more than 1 in a list, it appends as a nested list (i.e a list inside another list.)
To support my explanation you can see that your code fixed by a simple [0]
print(sorted(list1[0]))
That is because your input is stored as a list of list, AND it is stored in the first index (Point to note - 1st index in a python list is 0, hence the usage of list1[0])
Please let me know if I could have explained it in a more simpler way or if you have any other confusions that aid from the above explanation.

Simple way to remove duplicate item in a list [duplicate]

This question already has answers here:
How do I remove duplicates from a list, while preserving order?
(30 answers)
Closed 4 years ago.
the program says "TypeError: 'int' object is not iterable"
list=[3,3,2]
print(list)
k=0
for i in list:
for l in list:
if(l>i):
k=l
for j in k:
if(i==j):
del list[i]
print(list)
An easy way to do this is with np.unique.
l=[3,3,2]
print(np.unique(l))
Hope that helps!
Without using any numpy the easiest way I can think of is to start with a new list and then loop through the old list and append the values to the new list that are new. You can cheaply keep track of what has already been used with a set.
def delete_duplicates(old_list):
used = set()
new_list= []
for i in old_list:
if i not in used:
used.add(i)
new_list.append(i)
return new_list
Also, a couple tips on your code. You are getting a TypeError from the for j in k line, it should be for j in range(k). k is just an integer so you can't iterate over it, but range(k) creates an iterable that will do what you want.
Just build another list
>>> list1=[3,2,3]
>>> list2=[]
>>> for i in list1:
... if i in list2:
... pass
... else:
... list2.append(i)
...
>>> list2
[3, 2]
You can always add list1 = list2 at the end if you prefer.
You can use set()
t = [3, 3, 2]
print(t) # prints [3, 3, 2]
t = list(set(t))
print(t) # prints [2, 3]
To remove a duplicate item in a list and get list with unique element, you can always use set() like below:
example:
>>>list1 = [1,1,2,2,3,3,3]
>>>new_unique_list = list(set(list1))
>>> new_unique_list
>>>[1, 2, 3]
You have the following line in your code which produces the error:
for j in k:
k is an int and cannot be iterated over. You probably meant to write for j in list.
There are a couple good answers already. If you really want to write the code yourself however, I'd recommend functional style instead of working in place (i.e. modifying the original array). For example like the following function which is basically a port of Haskell's Data.List.nub.
def nub(list):
'''
Remove duplicate elements from a list.
Singleton lists and empty lists cannot contain duplicates and are therefore returned immediately.
For lists with length gte to two split into head and tail, filter the head from the tail list and then recurse on the filtered list.
'''
if len(list) <= 1: return list
else:
head, *tail = list
return [head] + nub([i for i in tail if i != head])
This is—in my opinion—easier to read and saves you the trouble associated with multiple iteration indexes (since you create a new list).

Python3 TypeError: list indices must be integers or slices, not str

i have the task to get the String 'AAAABBBCCDAABBB' into a list like this: ['A','B','C','D','A','B']
I am working on this for 2 hours now, and i can't get the solution. This is my code so far:
list = []
string = 'AAAABBBCCDAABBB'
i = 1
for i in string:
list.append(i)
print(list)
for element in list:
if list[element] == list[element-1]:
list.remove(list[element])
print(list)
I am a newbie to programming, and the error "TypeError: list indices must be integers or slices, not str" always shows up...
I already changed the comparison
if list[element] == list[element-1]
to
if list[element] is list[element-1]
But the error stays the same. I already googled a few times, but there were always lists which didn't need the string-format, but i need it (am i right?).
Thank you for helping!
NoAbL
First of all don't name your variables after built in python statements or data structures like list, tuple or even the name of a module you import, this also applies to files. for example naming your file socket.py and importing the socket module is definitely going to lead to an error (I'll leave you to try that out by yourself)
in your code element is a string, indexes of an iterable must be numbers not strings, so you can tell python
give me the item at position 2.
but right now you're trying to say give me the item at position A and that's not even valid in English, talk-less of a programming language.
you should use the enumerate function if you want to get indexes of an iterable as you loop through it or you could just do
for i in range(len(list))
and loop through the range of the length of the list, you don't really need the elements anyway.
Here is a simpler approach to what you want to do
s = string = 'AAAABBBCCDAABBB'
ls = []
for i in s:
if ls:
if i != ls[-1]:
ls.append(i)
else:
ls.append(i)
print(ls)
It is a different approach, but your problem can be solved using itertools.groupby as follows:
from itertools import groupby
string = 'AAAABBBCCDAABBB'
answer = [group[0] for group in groupby(string)]
print(answer)
Output
['A', 'B', 'C', 'D', 'A', 'B']
According to the documentation, groupby:
Make an iterator that returns consecutive keys and groups from the iterable
In my example we use a list comprehension to iterate over the consecutive keys and groups, and use the index 0 to extract just the key.
You can try the following code:
list = []
string = 'AAAABBBCCDAABBB'
# remove the duplicate character before append to list
prev = ''
for char in string:
if char == prev:
pass
else:
list.append(char)
prev = char
print(list)
Output:
['A', 'B', 'C', 'D', 'A', 'B']
In your loop, element is the string. You want to have the index.
Try for i, element in enumerate(list).
EDIT: i will now be the index of the element you're currently iterating through.

Resources