I want to read two unequal size python lists and write to the files. I can do this by repeating for-loops
with open(folder/'{}_matched_1_ids.txt'.format(f_1_latest[7:11]), 'a+') as matched_1_IDWriter, \
open(folder/'{}_matched_2_ids.txt'.format(f_1_latest[7:11]), 'a+') as matched_2_IDWriter:
for item in matched_1:
matched_1Writer.write("{},".format(item))
for item in matched_2:
matched_2Writer.write('{},'.format(item))
Instead of using 3 different for-loops, I could use itertools.zip_longest() with fillable option to none or "". But, I need nothing to fill (IGNORE) when loop's one iterator encounters nothing in the list to iterate over compared to other iterators.
Is there a way to do that?
I saw a similar pattern here but, didn't able to reproduce the solution in creating files.
Related
I have a simple problem. I'm new to python and programming so I think i miss something.
The variable "account_info" is assigned earlier and is a list of lists with 4 elements each. The variable current is a user input value, which (should) appear as the first element of the lists in the list account_info.
I want to iterate over the lists in the list and compare if the first element is equal to "current".
This is the code:
for i in account_info:
if current == account_info[i][0]:
email = account_info[i][1]
additional = account_info[i][2]
pw = account_info[i][3]
print(email)
I get an error in pycharm, when running that code. It seems that I can't iterate over the lists like that, can please someone explain and show a different solution?
Thank you
As #ForceBru commented, your issue is due to how for loops in Python work. The value you get from the loop is not an index into the iterable object you're looping on, rather, it's a value from the iterable. That makes your indexing with it later almost certainly wrong (though in certain contexts it might make sense, if you have a list that contains indexes into itself).
In your case, you probably want to do something more like this:
for account in accounts_info:
if current == account[0]: # note, only the inner indexing is needed
email = account[1]
additional = account[2]
pw = account[3]
Since you're expecting the inner lists to contain four values, you could even unpack the account values that you get from iterating directly into the inner variables. Though this would happen unconditionally, so it might not do what you want. Here's what that would look like, with the print call you were doing after the loop instead moved inside the conditional (so you only print the one email address that corresponds to the value in current):
for account_id, email, additional, pw in account_info: # unpack unconditionally
if account_id == current: # use the convenient name here
print(email) # print only in the conditional
In the rare case where you really do need to iterate over indexes, you can use the range type, which behaves like a sequence of integers (starting at zero by default). So you could replace your loop with this version and the body would work as you had intended (though this is less idiomatic Python than the previous versions).
for i in range(len(accounts_info)):
If you need both the index and the current value, you can use the enumerate function, which yields 2-tuples of index and value as you iterate over it. This is often handy when you need to reassign values in a list some times:
for i, account in enumerate(accounts_info):
if account[0] == current:
accounts_info[i] = new_value # replace the whole account entry
I am new to python3 and I want to get all the document suffix use:
dir_files = set(map(lambda f: f.split(sep='.')[1], os.listdir()))
but come with an error:
IndexError: list index out of range
However if I change [1] to [0] I can get all the filenames
correctly.
That's why? PLS help me.
If you want to get suffix of all documents, then you should go with some other approach. With this approach your program will fail for filenames like these:
my_doc - In this case, the file doesn't have any suffix. So, the split method will result will generate this list - ['my_doc']. Since this is a single element list, you're bound to get an IndexError.
my.doc.txt - Since more than 1 '.'s are present in this file name, the split method will generate this list - ['my', 'doc', 'txt']. Here, your code will give you doc as the file suffix even though real suffix is txt.
One may list more problems, because os.listdir() lists out directories and hidden files as well, but I won't talk about it since I don't know all about your task.
This is one possible solution that will work in most cases (not all cases):
dir_files = set(map(lambda f: os.path.splitext(f)[1][1:].lower(), os.listdir())) - {''}
In my recently migrated from 2 to 3 Python code I have
list(reversed(zip(*positions)))
which generates the error
TypeError: 'zip' object is not reversible
I can fix this by changing the problematic code to
list(reversed(list(zip(*positions))))
but this seems like the wrong way to go about it.
What is the correct way to revers a zip in Python 3?
reversed is used to iterate on the list. It doesn't create a list on purpose, because it's often used just to iterate backwards on elements, not to create lists.
That's why you have to use list on it to create a list. And it needs a sequence to be able to get to the last element directly so you have to do list(zip()) in python 3.
Maybe you could shorten
list(reversed(list(zip(*positions))))
to
list(zip(*positions))[::-1]
it creates a list directly without the need for reverse so it's probably slightly faster too.
listname = ['bartian', 'lenana', 'kilimanjaro', 'uhuru', 'elgon', 'everest']
while True:
if listname[:-1] == everest:
print(listname[:-1]+=)
I need a way to loop over this list and print the items in the list. I dont know whether this is pythonic since am having trouble printing the items. I want it to print from the last to first, middle item to lst or to first.
I think the easiest way to solve your task is by using a for loop on a slice of your original list.
for name in listname[::-1]:
print(name)
This prints the names in reverse order. The [::-1] slice says to go from one end to the other, with a step size of -1. For this specific case, you could also use reversed, but if you want to do other kinds of slicing it might make sense to use a slice here too, for symmetry.
Here are slices for the other forms you wanted:
for name in listname[len(listname)//2:]: # iterate on a slice from middle to end
print(name)
for name in listname[len(listname)//2::-1]: # slice from the middle back to the start
print(name)
Your code also has an if statement in it, but you don't describe what you want for it to do. If you're only printing names that are "everest" there's not much point to the loop!
Is there an easy way to create a set of strings in Matlab?
I am going through a list of filepaths and want to get all names of folders at a specific level.
But since in some folders there are several files, I get these folders several times.
I know there would be the possibility to create a cell array and check every time if the current folder name is already in the array, and if not, add it.
Another option would be to use the java HashSet class.
But is there any easy inbuilt Matlab way to do something like that?
I can't use a Vector since it would create a vector of chars not strings.
Unfortunately there's nothing as efficient as Java Set implementations.
But you can use set operations. Either union when you add, or just call unique on your collection with duplicates.
You could use the rdir script... MATLAB file exchange to the rescue!
Use it like this:
listing = rdir(name);
The function returns a structure listing similar to the built-in dir command.
It should save you the headache of iterating through a directory tree yourself.
How about "unique":
x = {'dog', 'cat', 'cat', 'fish', 'horse', 'bird', 'rat', 'rat'};
x_set=unique(x)
x_set =
'bird' 'cat' 'dog' 'fish' 'horse' 'rat'