I want to create a code that can append a file to a list, strip and split it, and find lines from Payments.txt that matches with the rule, which is find a customer that has a status of "A" AND still has outstanding money to pay. I can do the first two criteria's and can do the third one partially. I can find the customers that has amounts outstanding, but not the ones that has a status of "A". I have to use a list, not a dictionary by the way.
This is my code below:
myList = []
Status = "A"
myFile = open("Payments.txt")
record = myFile.readlines()
for line in record:
myList.append(line.strip().split(','))
myFile.close()
for z in record:
details = [[x for x in myList if x[0] == Status], [x for x in myList if x[2] > x[4]]] #This is were I am having trouble
if details:
print(details)
break
And this is the result:
[[], [['E1234', '12/09/14', '440', 'A', '0'], ['E3431', '10/01/12', '320', 'N', '120'], ['E5322', '05/04/02', '503', 'A', '320'], ['E9422', '26/11/16', '124', 'N', '0']]]
Why am I getting an empty list at the start of the result? There isn't a blank line in Payments.txt.
The list structure is as follows:
['Customer number', 'Date when they joined', 'Total amount', 'Status', 'Amount paid']
Try this:
[x for x in myList if len(x) == 5 and x[3] == Status and x[2]>x[4]]
In len(x) == 5, 5 represents the length of the normal list structure. It preferable to replace it by a variable.
Try this:
details = [[x for x in myList if x[0] == Status and x[2] > x[4]]
I think the reason why you're getting one is because you check either A or the greater than.
Related
Assume I have a list=[1,2,3,4] then I want to make a list of strings which length of each string associated with corresponding value in a list.
It means the final output should be like this:
strs=['1', '11', '111', '1111']
I tried the code below but I am not sure how to continue.
lis=[1,2,3,4]
strs=[]
for i in range (len(lis)):
st=lis[i]
strs.append(st)
The multiplication for strings is repetition, so:
lst=[1,2,3,4]
result = []
for e in lst:
result.append('1'*e)
print(result)
Output
['1', '11', '111', '1111']
You first need to loop over the list of lengths lis
Then in each iteration looping n times (the given length of that iteration) and appending 1 each time to the newStr.
And after the iteration adding the newStr to the list strs
lis = [1,2,3,4]
strs = []
for n in lis:
newStr = ""
for x in range(n):
newStr += str('1')
strs.append(newStr)
I have an example:
list = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
for i in range(len(list)):
if list[i][-1] == "last":
del(list[i+1])
del(list[i])
I'd like to delete this list where the last item is "last" and the next item on the list.
In this example there is a problem every time - I tried different configurations, replacing with numpy array - nothing helps.
Trackback:
IndexError: list index out of range
I want the final result of this list to be ['3', '4', 'next']
Give me some tips or help how I can solve it.
Try this:
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
delete_next = False
to_ret = []
for x in l:
if x[-1] == 'last':
delete_next = True
elif delete_next:
delete_next = False
else:
to_ret.append(x)
Using a variable to store if this needs to be deleted
Loop over the list, if the last element of that iteration == 'last' then skip, else, append to a new list.
Also, it is not recommended to edit lists while iterating over them as strange things can happen, as mentioned in the comments above, like the indexes changing.
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
newlist = []
for i in l:
if i[-1] == 'last':
continue
else:
newlist.append(i)
could you please tell me how to have the following output using the code below?
Input list:
list_1 = ["A","house","49","apartment","AD","Luke","17","17","Mike","8","B","Eliz","22","www.odeon.com","64", "holidays"]
Code:
def splitting(N):
for i in len(list_name):
yield list_name[i:i + N]
Expected output:
1st group: ["A","house","49","apartment","AD"]
2nd group: ["Luke","17","17","Mike","8"]
3rd group: ["B","Eliz","22","www.odeon.com","64"]
4th group: ["holidays]
I have followed most of the previous questions that have been already published in stackoverflow, but I am still having difficulties. Since it might be a duplicated question, I would like to ask if it would be possible to help me to figure out with this function and the expected output before closing. Most of you have experience with Python: I am a beginner with lots of questions and with the necessity of asking a couple of them to learn more, even by my own mistakes.
Thank you
You can use a for loop with a skip and then yield slices:
list_1 = ["A","house","49","apartment","AD","Luke","17","17","Mike","8","B","Eliz","22","www.odeon.com","64", "holidays"]
def splitting(a_list, N):
for i in range(0, len(a_list), N):
yield a_list[i:i + N]
for item in splitting(list_1, 5):
print(item)
Prints:
['A', 'house', '49', 'apartment', 'AD']
['Luke', '17', '17', 'Mike', '8']
['B', 'Eliz', '22', 'www.odeon.com', '64']
['holidays']
Right now, i is being incremented by one each time. So the second yield will return with ['house', '49', ...] (a total of N items). Instead, you want i to be incremented by N each time. You can accomplish that like this:
def splitting(N):
i = 0
while i < len(list_name) - N:
yield list_name[i:i + N] # while condition prevents IndexError
i = i + N
if i < len(list_name):
yield list_name[i:] # Yield what remains of the list
I'm in an Intro to Python class and was given this assignment:
Given a list of strings, return a new list containing all the strings from the original list that begin and end with the same character. Matching is not case-sensitive, meaning 'a' should match with 'A'. Do not alter the original list in any way.
I was running into problems with slicing and comparing the strings because the possible lists given include '' (empty string). I'm pretty stumped and any help would be appreciated.
def first_last(strings):
match=[]
x=''
count=0
while count<len(strings):
if x[0] == x[-1]:
match.append(x)
x+=x
count+=1
So, when given:
['aba', 'dcn', 'z', 'zz', '']
or
['121', 'NbA', '898', '']
I get this:
string index out of range
When I should be seeing:
['aba', 'z', 'zz']
and
['121', '898']
Your list contains an empty string (''). Thus, you will have to check for the length of each element that you are currently iterating over. Also, it does not seem that you use x:
def first_last(strings):
match=[]
count=0
while count<len(strings):
if strings[count]:
if strings[count][0].lower() == strings[count][-1].lower():
match.append(strings[count])
count += 1
return match
Note, however, that you can also use list comprehension:
s = ['aba', 'dcn', 'z', 'zz', '']
final_strings = [i for i in s if i and i[0].lower() == i[-1].lower()]
def first_last(strings):
match=[]
for x in strings:
if x is '' continue;
if x.lower()[0] == x.lower()[-1]:
match.append(x)
return match
Test if the list element is not None first:
def first_last(strings):
match = []
for element in strings:
if element and element[0].lower() == element[-1].lower():
match.append(element)
return match
or with list comp:
match = [element for element in strings if element and element[0].lower() == element[-1].lower()]
Task
I am trying to assign an number identifier for words in a string.
Code
I have currently done the following:
mystr = 'who are you you are who'
str_values = mystr.split()
list_values = [str(i) for i, w in enumerate(mystr.split())]
Output:
>>> str_values
['0', '1', '2', '3', '4', '5']
>>> list_values
['who', 'are', 'you', 'you', 'are', 'who']
Query/Desired Output
mystr contains repeating words, and so I would like to assign each word a number rather than different numbers each time but aren't sure how I should begin doing so. Therefore, I would like list_values to output something along the line of:
['0', '1', '2', '2', '1', '0']
You could do this with help of another list -
n = []
output = [n.index(i) for i in mystr.split() if i in n or not n.append(i)]
First n is empty list. Now list comprehension iterate over all the element of mystr.split(). It adds the index of the element in list n if condition met.
Now for the condition. There are two parts with an or. First it checks if the element is present in n. If yes, then get the index of the element. If no, it goes to the second part, which just appends the element to the list n. Now append() returns None. That is why I added a not before it. So, that condition will be satisfied and it will give the newly inserted elements index.
Basically the first part of if condition restricts duplicate element addition in n and the second part does the addition.
Well we can work in two phases:
first we construct a dictionary that maps words on indices, given they do not exist yet, and
next we use the dictionary to obtain the word identifiers.
Like:
identifiers = {}
idx = 0
for word in mystr.split():
if word not in identifiers:
identifiers[word] = idx
idx += 1
list_values = [identifiers[word] for word in mystr.split()]
This generates:
>>> [identifiers[word] for word in mystr.split()]
[0, 1, 2, 2, 1, 0]
If you want, you can also convert the identifiers to strings, with str(..), but I do not see why wou would do that:
>>> [str(identifiers[word]) for word in mystr.split()]
['0', '1', '2', '2', '1', '0']
The algorithm will usually work in O(n).
You need to use a dictionary to keep track of which words have already been seen
word_map = {}
word_id_counter = 0
def word_id(word):
global word_id_counter
if word in word_map:
return word_map[word]
else:
word_map[word] = word_id_counter
word_id_counter += 1
return word_map[word]
To avoid using global variables you can wrap it in a class
class WordIdGenerator:
word_map = {}
word_id_counter = 0
def word_id(self, word):
if word in self.word_map:
return self.word_map[word]
else:
self.word_map[word] = self.word_id_counter
self.word_id_counter += 1
return self.word_map[word]
And you can use it like this:
gen = WordIdGenerator()
[gen.word_id(w) for w in 'who are you you are who'.split()]
And the output will be:
[0, 1, 2, 2, 1, 0]