concatenate items on list using range loop and append - python-3.5

I am trying to concatenate the strings in a given list using a loop and the append function. (I know I can use the join function, but I am trying it for practice.)
The error I am getting is:
Traceback (most recent call last):
File "trial1.py", line 4, in
q.append(lista[i])
AttributeError: 'set' object has no attribute 'append'
Here is my code:
lista = {'a','p','o','o','r','v','e'}
q = lista
for i in range(7):
q.append(lista[i])

What you should do when you have a list of strings that you want to concatenate into a single string:
print(''.'join(['a','p','o','o','r','v','e']))
To see a similar solution using an explicit loop, we can use the concatenation operator + to join strings.
lista = ['a','p','o','o','r','v','e']
res = ''
for s in lista:
res = res + s
print(res)
Note that + doesn't change the strings it acts upon because strings are immutable.

Related

Getting error when using while loop to filter duplicates out from a list

I'm trying to open a txt file and get all the words in it, assign it to a list, and filter the list of duplicates. The code in the snippet is what I thought would work, but I'm getting a traceback error and it says list index is out of range. How can I modify my code to avoid that error?
Any help is appreciated.
fname = input("Enter file name: ")
fh = open("romeo.txt")
lst = list()
for line in fh:
nlst = (line.rstrip()).split()
lst = lst + nlst
for i in [*range(len(lst))]:
if lst.count(lst[i]) > 1:
while lst.count(lst[i]) > 1:
print(lst[i])
lst.remove(lst[i])
else:
continue
print(lst)
edit 1:
Okay so I thought the cause of the problem was lst.count(lst[i]) having a value of one or more and the inequality is (>1) so it's saying that it's out of range, but I tried 0 instead of 1, and it still gave me the same error.
vsc snippet
but i'm getting a traceback error and it says list index is out of range
First, whenever you're asking about a traceback, include the actual error message in your question. In this case, that looks like:
Traceback (most recent call last):
File ".../countwords.py", line 9, in <module>
if lst.count(lst[i]) > 1:
~~~^^^
IndexError: list index out of range
There are several issues that get us into this situation. Broadly, you're iterating over the number of words in the document. For each word, you're using lst.count to find occurrences of the word in lst...and then removing duplicates. Whenever you find a duplicate, lst gets shorter, but your outer loop doesn't know this. Eventually, you ask for lst[i] when i is larger than the length of the list and your code explodes.
We can fix this while preserving your current logic by making a couple of changes.
First, let's fix that outer loop; you've written for i in [*range(len(lst)], but that's operationally equivalent to for i in range(lst), which is simpler to read.
Instead of trying to update lst, let's populate a new variable lst_no_dupes; this avoids issues with modifying lst while at the same time trying to iterate over it:
Instead of using lst.count, we can use the in operator to check for the presence of a word in a list.
Those changes get us:
lst_no_dupes = []
for i in range(len(lst)):
if lst[i] not in lst_no_dupes:
lst_no_dupes.append(lst[i])
print(lst_no_dupes)
This works, but it's inefficient, because checking to see if a word is contained in the list is an O(n) operation. As the number of words grows larger, it will take longer and longer to look up items in the list.
There's a much simpler way to produce a list of unique items from a list as long as you don't care about their order: just turn them into a set:
fh = open("romeo.txt")
lst = list()
for line in fh:
nlst = (line.rstrip()).split()
lst = lst + nlst
lst = set(lst)
print(lst)
A set is "an unordered collection of distinct objects"; lookups in a set are O(1) so the time required to check for a duplicate is independent of the number of words.
Ultimately, you could simplify everything down to this:
with open('romeo.txt') as fh:
lst = set(word for line in fh for word in line.split())
print(lst)
Here, we're iterating over lines in the file (for line in fd) and then words in each line (for word in line.split()). This is an example of a generator expression (which is like a list comprehension).

python: how to add a key-value pair to the beginning of a nested dictionary?

i need to add to the beginning of a nested dictionary. it looks like move_to_end() is the easiest way for us to accomplish this but it seems that i cannot use this in a nested dictionary.
dict = OrderedDict({
'abdomen' : {"liver":3 , "spleen":1},
})
dict['abdomen'].update({'stomach':'2'})
dict['abdomen'].move_to_end('stomach', last = False)
print(dict['abdomen'])
generates the error:
Traceback (most recent call last):
File "test.py", line 232, in
dict['abdomen'].move_to_end('stomach', last = False)
AttributeError: 'dict' object has no attribute 'move_to_end'
The inner dictionary must be an OrderedDict. Change to the following:
my_dict = OrderedDict({
'abdomen': OrderedDict({"liver": 3, "spleen": 1}),
})
Note: Using built-in names (e.g., dict) is a bad idea. Change dict to something suitable.

How to solve ValueError is not in List? It's in the list

How to solve ValueError is not in List problem? I don't understand what is wrong with my code.
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://uk.reuters.com/business/quotes/financialHighlights? symbol=AAPL.O")
bsObj = BeautifulSoup(html,"html.parser")
tag = bsObj.findAll("td")
tagList = []
for tagItem in tag:
tagList.append(tagItem)
print(tagList.index("<td>Dec</td>"))
Error:
Traceback (most recent call last):
File "/Users/home/Desktop/development/x/code.py", line 11, in <module>
print(tagList.index("<td>Dec</td>"))
ValueError: '<td>Dec</td>' is not in list
Process finished with exit code 1
You're creating a list of <class 'bs4.element.Tag'> objects. Their string representation seems to match the string you're looking for, except that objects are not equal since they have different types.
(note that printing the list yields [<td>Dec</td>, <td>Dec</td>], note the absence of quotes, printing the same list but with strings yields ['<td>Dec</td>', '<td>Dec</td>'])
Quickfix: create your list as string
for tagItem in tag:
tagList.append(str(tagItem))
or as list comprehension:
tagList = [str(tagItem) for tagItem in tag]
Now index works: returns "0"
Note that you could keep your list unconverted (if you want to keep the objects, not coerce to strings), and use the following to find the first index compared to a string:
print(next(i for i,x in enumerate(tagList) if str(x)=="<td>Dec</td>"))

Function not returning the Value of its Key

I'm writing a function that constructs a dictionary from a given file. The file contains lines of data like: 7576240,Sigrid,Rahn. The number is an ID, and the rest is a first and second name. my task is to create a dictionary with the ID as a Key and the the first and last name as a Value in a tuple format.
I have managed to do so, but when i try to do this :
students_dict = read_class_from_file('class1.txt')
print(students_dict['7576240'])
it returns the:
2365568 : ('Josef', 'Krten')
3544826 : ('Bernadene', 'Klimas')
5215521 : ('Florie', 'Starkebaum')
6914206 : ('Minnaminnie', 'Sridhar')
7576240 : ('Sigrid', 'Rahn')
8963113 : ('Sharri', 'Benyon')
Traceback (most recent call last):
File "<string>", line 2, in <fragment>
builtins.TypeError: 'NoneType' object is not subscriptable
I think the dictionary is working fine, untill i call a Key to get its Value,can someone help with this?
My code:
def read_class_from_file(filename):
''' function reads all data in (filename) and returns a dictionary '''
dictionary = {}
lines = []
data = [line.strip() for line in open(filename, 'r')]
for line in data[1:]:
lines += [line.split(",")]
for lina in lines:
dictionary[lina[0]] = (lina[1], lina[2])
for key in sorted(dictionary.keys()):
print("{0} : {1}".format(key, dictionary[key]))
You're not returning anything from your function.
You'll have to add
return dictionary
to the end of your definition of read_class_from_file. Since it doesn't currently return anything, students_dict is None.

List created outside of for loop forgotten by python when I .append()

I am trying to iterate through a string and write characters to a list (with a 'for' loop). If I create the empty list before the for loop, python thinks its a string when I get to myList.append(stuff) It works if I create the empty list in the loop, but the obviously it gets erased at each iteration. I've tried to play with global stuff but I'm not getting anywhere. *This is supposed to be a very simply cipher, a warm-up to a bigger project but this is holding me up.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
while True:
code = []
index = int(input("Code Index:"))
message = input("Message: ")
for i in message:
if i in alphabet:
value = alphabet.find(i)
value += index
new_letter = alphabet[value]
print('new letter: ' + new_letter)
code.append(new_letter)
print('code: ' + str(code))
else:
code.append(i)
code = ''.join(code)
input("EXPORT CODE: ")
print(code)
But when this runs I get:
<i>Traceback (most recent call last):
File "C:/Users/Max Hayes/Desktop/PyCrypt/test.py", line 15, in <module>
code.append(new_letter)
AttributeError: 'str' object has no attribute 'append'</i>
code = ''.join(code) you rebind code to a str class, that's why you have the problem. Probably you can change it to code_str = ''.join(code) . In addition, this statement need to be put outside of the for loop.

Resources