I have a list of objects, each of which has a list of things. I wish to create a list of the things held in all of the objects. Is there a more pythonic way of doing this?
class Holder(object):
def __init__(self, things):
self.things = things
holder_one= Holder([1, 2])
holder_two = Holder(['a', 'b'])
holders = [holder_one, holder_two]
all_things = []
for holder in holders:
for thing in holder.things:
all_things.append(thing)
print all_things
You could either:
Make Holder inherit from list then this becomes pretty trivial.
Use extend instead of append, which will save you an explicit loop:
all_things = []
for holder in holders:
all_things.extend(holder.things)
print all_things
Related
Ive got a function named allAppointmentList to get Appointments from the server using a GET method in AppointmentProvider class.
In my MyAppointments class I have initialized 2 lists named as appointment and allAppointments as below,
class _MyAppointmentState extends State<MyAppointment> {
bool isLoading = true;
List<Appointment> allAppointments=[];
List<Appointment> appointments = [];
And in the init state I have assigned the data I get from the allAppointmentList method to the 2 lists mentioned above.
#override
void initState() {
super.initState();
_loadAppointments();
}
_loadAppointments() async {
final AppointmentProvider appointmentProvider =
Provider.of<AppointmentProvider>(context, listen: false);
await appointmentProvider.getAllAppointments();
setState(() {
isLoading = false;
appointments = appointmentProvider.allAppointmentList;
allAppointments = appointmentProvider.allAppointmentList;
});
}
when I change one list the other changes as well.For example,
if I clear the appointments list,allAppoitments list gets cleared as well.If I remove the element in the second index of the appointments list,the element in the second index of the allAppointments list gets removed as well.
How can I make these two list act independently ?
Your problem is probably that you think this creates new lists:
appointments = appointmentProvider.allAppointmentList;
allAppointments = appointmentProvider.allAppointmentList;
My guess is that appointmentProvider.allAppointmentList returns the same List instance every time which is a problem here since you are then just assigning the same List object to both appointments and allAppointments.
I am not sure if you also want copies of all the objects inside the lists but if you just want to have independent lists which then contains references to the same objects, the safest would just be to do:
appointments = appointmentProvider.allAppointmentList.toList();
allAppointments = appointmentProvider.allAppointmentList.toList();
This will create new lists which then contains the same objects from appointmentProvider.allAppointmentList. But you can then delete/add elements to each of these lists without this change also happening to the other lists.
appointments and allAppointments are currently just references to appointmentProvider.allAppointmentList. You can create new instances as follows:
appointments = [...appointmentProvider.allAppointmentList];
allAppointments = [...appointmentProvider.allAppointmentList];
This uses a list literal [] in combination with the spread operator ... to create a new list with the same elements. Note that the elements themselves are still references to their original instances and are not deep copies.
I want to have an immutable list, since I don't really need the mutability so it likely to just cause bugs. However, the list is a lateinit var declared at the class level.
I want to initially populate the list with values from a loop somewhat like this:
for (items in someOtherCollection) {
val itemToAdd = doSomeProcessingOnThisData()
list.add(itemToAdd)
}
However, since the list is immutable, I can't call add(). Is there a better way to init a list such as this without simply adding all the values to a second, mutable list and then assigning it to an immutable list?
My current solution is this, but it just seems inefficient:
val tmpList = mutableListOf<Data>()
foos.forEach() {
val itemToAdd = doSomeProcessing()
foos.add(itemToAdd)
}
this.list = tmpList
If you want to make a new list processing some data in another collection, try this:
this.list = someOtherCollection.map {
doSomeProcessing()
}
Give this a read for a better understanding: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html
I wanted to have a Queue class that could be used the same way as a list.
For instance,
val q = Queue()
would instantiate an empty queue.
For that purpose I tried using a companion class :
object Queue {
def apply() = new Queue[Any]
}
Is that the right way to do it ?
Using the apply method of the companion object is the right way to do it, but you could also add a type parameter on apply itself:
object Queue {
def apply[T]() = new Queue[T]
}
So that you can create a Queue of the right type:
val q = Queue[Int]()
Usually you also allow populating the sequence on creation, so that the element type can be inferred, as in:
def apply[T](elms: T*) = ???
So that you can do:
val q = Queue(1,2,3) // q is a Queue[Int]
Yes.
If you want to initialise an object without using new, then using apply() as a factory method in the companion is absolutely the right way to go about it.
You might also want to consider a more specific factory (or factories) to help make your code more self-documenting.
object Queue {
def apply[T](xs: T*) = new Queue(xs: _*)
def empty[T] = new Queue[T]()
}
So I have the following class object:
class Bond(object):
def __init__(self, Atom1=None, Atom2=None):
self.atoms = [Atom1, Atom2]
where Atom1 and Atom2 are mutable objects.
and I have:
>>> first_bond
Bond(Atom1, Atom2)
>>> second_bond
Bond(Atom1, Atom3)
>>> third_bond
Bond(Atom2, Atom1)
and also have:
>>> bonds
[first_bond, second_bond, third_bond]
If you realize, the first_bond and third_bond are the same since one is the reverse of the other, this is:
>>> first_bond == third_bond[::-1]
True
So my question is how can I implement a function or something that can filter only distinct objects, so that my final bonds is:
>>> bonds
[first_bond, second_bond]
I have read that maybe using __eq__ and __hash__ method would be a solution, and then using set(bonds). But since Atoms are mutable objects I don't know if this is kind of possible.
I'm sure there is a way to do this, but I'm really stuck on this one.
I have a domain model that connects to entities Foo and Bar in a many-to-many-relationship. Now when I want to list all Foos to a certain Bar, I do the query and get a lot of FooBar objects. I iterate through these objects and add all Foos to a list.
Like so:
def fooBarRelations = FooBar.findAllByBar bar
def fooList = []
fooBarRelations.each { fooList.add it.foo }
How can I sort the fooList based upon the parameters a g:sortableColumn adds to the url namely sort (the field to sort) and order.
I know you can pass the parameters to the query directly but I think this is not possible in my case?
So how can I either
Make one query without list iterating so I can pass in the sorting parameters OR
Sort my custom list based upon the sorting parameters?
Addition 1 (03/25/2012)
If I could to this ...
def fooBarRelations = FooBar.findAllByBar bar, [sort: 'foo.' + params.sort, order: params.order]
... the problem would be solved. But passing this to the query does not have any effect on the output. Is there any way I can sort a query by a sub-property?
If you really can't sort within the query itself. Then you need a list of lists.
List<List<Fields>> mylist;// where List<Fields> is a lists of the fields.
Then use a Comparator to sort your List> by the desired filed. Say your desired field is at index 3:
new Compare(List<Fields> L1, List<Fields> L2){
if(L1.get(3)>L2.get(3))
return -1;//etc.
UPATE BASED ON COMMENT:
say your entity is as follows
public class Entity{
String name, address, school;
Integer bankaccount;
//etc...
}
Then
public class WhereISort{
List<Entity> myList;
String mysorter;//mysorter can be declared here as static final
public WhereISort(){//maybe pass list in here or whatever
}
public Response myWebService(params..., String sorter){
mysorter=sorter;//mysorter can be declared here as static final
Collections.sort(myList, new Comparator() {
public int compare(Entity e1, Entity e2) {
if(mysorter.equalsIgnoreCase("name")){
return e1.getName().compareToIgnoreCase(e1.getName());
}else if(mysorter.equalsIgnoreCase("bankaccount")){
//your code here, etc.
}
}
});
}
}
Of course, the main point is using "mysorter" and the inner class "Comparator" to sort