Equating a list to the function of another list - python

At the moment, I have a piece of code with lots of lists equal to the function of another list, embedded in a loop in Python:
Power = [x,y,z]
Force = []
for i in range(len(Power)):
Force.append(((function(Power[i])-0.5))/slope)
I would like to simplify it down to:
Force = function(Power[i])-0.5))/slope)
but it doesn't work. It does however work when there's no function, just a simple relationship. Is this possible in Python?

You can use a list comprehension:
Force = [(function(x)-0.5)/slope for x in Power]

As far as I am aware the most concise / simplest way to do this is via list comprehension, in particular you can do something as follows:
Force = [(function(Power[i])-0.5)/slope for i in range(len(Power))]
Very similar to what you have already done earlier, but comes in a nice and simple one line expression.

Related

Why is Map function not computing my lambda?

So I'm trying to use the map function with a lambda to write each item of a list to a txt file on a new line
map(lambda x: text_file.write(f"{x}\n"), itemlist_with_counts_formatted)
I understand that map returns a map object, but I don't need the return value.
What I want is for the map function to compute the lambda, which adds "\n" to the end of each item in the given list.
I thought that map should do this (compute the function (lambda appends "\n") using arguments from the iterable) but nothing gets output to the txt file.
For clarity, I can totally do this with a list comprehension but I wanted to learn how to use map (and properly anonymous lambdas), so am looking for help solving it using these two functions specifically (if possible).
map(lambda x: text_file.write(f"{x}\n"), itemlist_with_counts_formatted)
I have also tried it without the f string, using just x + "\n" but this doesn't work either
Yes the txt file is open, and yes I can get it to work using other methods, the problem is exclusive to how I'm using map or how I'm using lambda, which must be wrong in some way. I've been doing this for 6 weeks so its probably something stupid but I've tried to figure it out myself and i just can't and I've checked but can't find anything on here - appreciate any help I can get.
You should really not use map for this task.
It looks fancy, but this is the same as using list comprehensions for side effects. It's considered bad practice.
[print(i) for i in range(3)]
Which should be replaced with:
for i in range(3):
print(i)
In you case, use:
for item in itemlist_with_counts_formatted:
text_file.write(f"item\n")
why your code did not work:
map returns a generator, nothing is evaluated until something consumes the generator. You would need to do:
list(map(lambda x: text_file.write(f"{x}\n"), itemlist_with_counts_formatted))
But, again, don't, this is useless, less efficient and less explicit.
But I really want a one-liner!
Then use:
text_file.write('\n'.join(itemlist_with_counts_formatted))
NB. unlike the other alternatives in this answer, this one does not add a trailing '\n' in the end of the file.
I really, really, want to use map:
text_file.writelines(map(lambda x: f'{x}\n', itemlist_with_counts_formatted))
i think that the problem is that this use of the map function is a bit unproper. As said in the documentation the map function returns a generator for the results iterable, while the write function is not returning anything. This might brake something during the map internals.
I'd suggest you to use map only to add line end and then use the writeline function on the resulting generator, something like:
text_file.writelines(map(lambda x: f"{x}\n", itemlist_with_counts_formatted))
(Not tested)

How can I pass each element of a set to a function?

I have a set with multiple tuples: set1 = {(1,1),(2,1)} for example.
Now I want to pass each tuple of the set to a method with this signature: process_tuple(self, tuple).
I am doing it with a for loop like this:
for tuple in set1:
process_tuple(tuple)
Is there a better way to do it?
Your question is basically "how can I loop without using a loop". While it's possible to do what you're asking with out an explicit for loop, the loop is by far the clearest and best way to go.
There are some alternatives, but mostly they're just changing how the loop looks, not preventing it in the first place. If you want to collect the return values from the calls to your function in a list, you can use a list comprehension to build the list at the same time as you loop:
results = [process_tuple(tuple) for tuple in set1]
You can also do set or dict comprehensions if those seem useful to your specific needs. For example, you could build a dictionary mapping from the tuples in your set to their processed results with:
results_dict = {tuple: process_tuple(tuple) for tuple in set1}
If you don't want to write out for tuple in set1 at all, you could use the builtin map function to do the looping and passing of values for you. It returns an iterator, which you'll need to fully consume to run the function over the full input. Passing the map object to list sometimes makes sense, for instance, to convert inputs into numbers:
user_numbers = list(map(int, input("Enter space-separated integers: ").split()))
But I'd also strongly encourage you to think of your current code as perhaps the best solution. Just because you can change it to something else, doesn't mean you should.

Is there a more Pythonic way to loop through a list and then have each loop variable update a dictionary?

I am trying to write a more pythonic or a more concise way and avoid writing too many for loops.
Basically I have the following block code:
result = {}
for model_name in list_of_model_names:
model_fields = _do_something(model_name)
result['{}_fields'.format(model_name)] = model_fields
return result
In essence, I am looping through a list of strings. Each string I will perform some action so that some derivative of that string becomes a key and value pair in a dictionary.
I am reading through http://www.u.arizona.edu/~erdmann/mse350/topics/list_comprehensions.html
I know that :
Map returns a list
Filter reduces the number of elements
Reduce looks like it will return the native data type within the list. Maybe string or number depending on the original list.
My code is working, I was wondering if there's a more concise or a more pythonic way to loop through a list and have its loop variable affect the key and value of a dictionary.
Generally, the more Pythonic way is not to use map, filter, and reduce, but to use comprehensions.
For your code, that would be
result = {'{}_fields'.format(model_name): _do_something(model_name)
for model_name in list_of_model_names}
Comprehensions can also work for lists and sets.
You can be more concise using:
result = {(name+'_fields'): _do_something(name) for name in list_of_model_names}
Whether that's more readable, or useful is up to you though.

Python For Loop to List

I have a beginner Python question. I was wondering if it was possible to take the results of a for loop that came from a list and then turn it back into a list again. I've got code that looks something like this.
for a in mylist:
result = q.myfunction(a)
print q, a
I would like the results of this list to be something that I can use to create a table in my database. I am using Python 2.7 on Windows 7. I have looked through the documentation from python on for loops, and looked through questions on stack exchange, and I am still confused.
Sure.
Just printing things out obviously doesn't append them to a list. But calling the append method on a list does, as explained in the Lists section of the tutorial. For example:
mynewlist = []
for a in mylist:
result = q.myfunction(a)
print q, a
mynewlist.append(result)
If all you want to do is create a new list, no other side effects, a list comprehension makes it even simpler. This code:
mynewlist = [q.myfunction(a) for a in mylist]
… does the same as the above, but without the print.
If you're used to using for loops then you can do the following:
results = []
for a in mylist:
result = q.myfunction(a)
results.append(result)
However, the idiomatic way to do something like this in python is to use what's known as a list comprehension. List comprehensions are a way of producing new lists from the elements of others lists. For example, the following has exactly the same effect as the above for loop.
results = [q.myfunction(a) for a in mylist]
Is this what you want?
[q.myfunction(a) for a in mylist]
It's called a list comprehension.

Efficient use of Python list comprehensions

I have a Python list of objects that could be pretty long. At particular times, I'm interested in all of the elements in the list that have a certain attribute, say flag, that evaluates to False. To do so, I've been using a list comprehension, like this:
objList = list()
# ... populate list
[x for x in objList if not x.flag]
Which seems to work well. After forming the sublist, I have a few different operations that I might need to do:
Subscript the sublist to get the element at index ind.
Calculate the length of the sublist (i.e. the number of elements that have flag == False).
Search the sublist for the first instance of a particular object (i.e. using the list's .index() method).
I've implemented these using the naive approach of just forming the sublist and then using its methods to get at the data I want. I'm wondering if there are more efficient ways to go about these. #1 and #3 at least seem like they could be optimized, because in #1 I only need the first ind + 1 matching elements of the sublist, not necessarily the entire result set, and in #3 I only need to search through the sublist until I find a matching element.
Is there a good Pythonic way to do this? I'm guessing I might be able to use the () syntax in some way to get a generator instead of creating the entire list, but I haven't happened upon the right way yet. I obviously could write loops manually, but I'm looking for something as elegant as the comprehension-based method.
If you need to do any of these operations a couple of times, the overhead of other methods will be higher, the list is the best way. It's also probably the clearest, so if memory isn't a problem, then I'd recommend just going with it.
If memory/speed is a problem, then there are alternatives - note that speed-wise, these might actually be slower, depending on the common case for your software.
For your scenarios:
#value = sublist[n]
value = nth(x for x in objList if not x.flag, n)
#value = len(sublist)
value = sum(not x.flag for x in objList)
#value = sublist.index(target)
value = next(dropwhile(lambda x: x != target, (x for x in objList if not x.flag)))
Using itertools.dropwhile() and the nth() recipe from the itertools docs.
I'm going to assume you might do any of these three things, and you might do them more than once.
In that case, what you want is basically to write a lazily evaluated list class. It would keep two pieces of data, a real list cache of evaluated items, and a generator of the rest. You could then do ll[10] and it would evaluate up to the 10th item, ll.index('spam') and it would evaluate until it finds 'spam', and then len(ll) and it would evaluate the rest of the list, all the while caching in the real list what it sees so nothing is done more than once.
Constructing it would look like this:
LazyList(x for x in obj_list if not x.flag)
But nothing would actually be computed until you actually start using it as above.
Since you commented that your objList can change, if you don't also need to index or search objList itself, then you might be better off just storing two different lists, one with .flag = True and one with .flag = False. Then you can use the second list directly instead of constructing it with a list comprehension each time.
If this works in your situation, it is likely the most efficient way to do it.

Categories

Resources