0
votes

Sélectionnez l'objet avec une valeur plus grande d'un attribut spécifique

Je viens de commencer à apprendre Python, donc je ne connais pas les divers astuces ou outils, ni à la bonne façon de verser ma question. À cause de cela, j'ai été incapable de trouver des questions précédentes qui font ce que je cherche.

J'ai un code de travail décrit ici: p> xxx pré>

L'exemple de sortie est affiché. Ci-dessous: P>

Battle number 1
Jarebear and Kung Cows have entered the fight!
The winner is:  Kung Cows
Battle number 2
Jarebear and Kung Cows have entered the fight!
The winner is:  Kung Cows
Battle number 3


5 commentaires

Essayez auto.attanger = max (self.user1, auto.user2, clé = lambda u: u.speed) . Le seul problème est qu'il favorisera l'utilisateur1 lorsque la vitesse d'User1 et User2 est la même.


Dans mes déclarations if / else, je dois regarder la dextérité si la vitesse est la même. Toute façon d'inclure cela?


Pourquoi ne pas créer un def who_goes_first (user1, user2) méthode - mettez-y votre logique et s'ils dessinent, choisissez-en un aléatoire? Nettoie votre code de combat, crée un funciton avec une raison basse de changer et le rend plus évident ce qui se passe?


Je me sentais si je déplace les déclarations if / sinon dans une autre fonction, que je serais juste sur-ingénieur ce qui devrait être une solution simple


@Jaredc Oui, renvoyez simplement un tuple de ce que vous voulez sortir de la fonction Lambda. Dans ce cas, ce serait: self.attacker = max (auto.atanger1, auto.user2, clé = lambda u: (u.speed, u.dextérité)) Je recommande la suggestion à propos de affacter la logique dans sa propre méthode. En tant que développeur chevronné (plus de 20 ans d'expérience), je ne l'appellerais pas sur la sur-ingénierie, j'appellerais cela la rendant lisible et de fournir une séparation logique des responsabilités. :-)


7 Réponses :


0
votes

Vous pouvez en effet utiliser max () pour obtenir le utilisateur avec la plupart de la vitesse.

La manière de le faire est avec la touche argument que vous utilisez pour passer Une fonction de notation personnalisée qui prend chaque objet et renvoie une valeur ordonnable comme un flotteur ou INT. xxx

Le plus courant est de transmettre une fonction lambda anonyme que vous définissez avec la syntaxe : xxx

de sorte que le code ressemblerait à: xxx


2 commentaires

Existe-t-il un moyen de vérifier le score de dextérité (ou simplement d'en sélectionner un au hasard) si la vitesse des utilisateurs est la même?


Max retournera simplement le premier élément si tous les utilisateurs ont la même vitesse, alors mélanger la liste avant de faire le tour. Pour cela, faites simplement à partir d'importation aléatoire shuffle et utilisez cette fonction pour gâcher la liste avant.



0
votes

J'ai juste besoin d'une déclaration qui est comme auto.attanger = max (self.user1.speed, self.user2.speed) mais l'attaquant est réglé sur le utilisateur, pas la vitesse de l'utilisateur. p>

Vous pouvez utiliser p>

from operator import attrgetter
...
self.attacker = max(self.user1, self.user2, key=attrgetter('speed'))

1 commentaires

Existe-t-il un moyen de vérifier le score de dextérité (ou simplement d'en sélectionner un au hasard) si la vitesse des utilisateurs est la même?



1
votes

Créer de petites méthodes qui concentrent la logique ne sont pas "aériennes". Ils sont faciles à comprendre et n'ont pas besoin de changer pour de nombreuses raisons - par conséquent, ils sont terminés, de testet et inchangés la plupart du temps. XXX


Si vous aimez un teaser cérébral Vous pouvez aussi bien faire: xxx

qui tire parti de la tri de tuple qui trie basé sur le 1er élément, et lorsque les 1ères sont égales sur le 2e élément du tuple. Si les deux sont égaux, l'ordre reste comme (tri stable avec Timsort ).

doku:


3 commentaires

Si je peux apprendre à comprendre et à utiliser le "cérébrail teaser", je pense que je vais devenir un meilleur programmeur


@Jaredc vous pourriez - mais cela rendra le code seulement plus court - pas plus propre


Il y a eu une mine de connaissances offerte en réponse à ma question, et je pense que je peux prendre les choses de toutes les réponses et améliorer ma compréhension de Python. C'est la réponse qui correspond le mieux à mes besoins spécifiques, bien que de nombreuses réponses présentées puissent être utilisées pour atteindre les résultats souhaités.



3
votes

Le min et max Les fonctions acceptent une touche qui leur indique comment comparer les entrées. La clé accepte chaque entrée et renvoie la valeur réelle à comparer: xxx

pour un grand nombre de comparaisons, cela peut être réécrit comme xxx p > Si vous avez des vitesses égales, vous pouvez décider de comparer à l'aide d'un attribut différent. Cela se fait en comprenant que les séquences python sont comparées dans l'ordre lexicographique. C'est le plus facile à comprendre avec des chaînes, car il s'agit essentiellement de l'ordre du dictionnaire: par exemple. 'abc'> 'abb' car chaque élément est comparé dans l'ordre. La même chose s'applique aux listes et aux tuples: [1, 2, 3]> [1, 2, 2] .

afin d'utiliser la dextérité Attribut comme une replie pour une vitesse égale, faites xxx

ou xxx


0 commentaires

0
votes

Voici une réponse qui sépare la logique comme mentionné ci-dessus et utilise votre désir max d'origine. L'avantage de cette solution est que la logique pour déterminer la première attaque pourrait être facilement refactable. Changez simplement la commande (ou ajouter des attributs à) attribut_priority_order xxx

avec un peu d'abstraction supplémentaire, _compare_attributes peut être recyclé pour déterminer le gagnant aussi peut-être avec un deuxième attribut facultatif. Le retour de cette méthode est éventuellement un utilisateur s'il n'y a pas d'égalité.


0 commentaires

0
votes

Que diriez-vous de l'utilisation du fait que Python répertorie de sorte que votre mesure de capacité est la suivante:

def fight(a, b):
    return winner(a, b) if ability(a) >= ability(b) else winner(b, a)


0 commentaires

1
votes

Si vous souhaitez utiliser max code> avec vos objets, vous pouvez implémenter __ gt __ code> com le comparez (et __ eq __ code> pour la cohérence). Donc, votre classe code> utilisateur code> pourrait ressembler à ceci:

class Battle:
    def __init__(self, user1, user2):
        self.user1 = user1
        self.user2 = user2
        print(user1, "and", user2, "have entered the fight!")

    def fight(self):
        self.user1.fight_stat()
        self.user2.fight_stat()

        self.attacker = max(self.user1, self.user2)
        self.defender = min(self.user1, self.user2)

        if self.attacker.attack > self.defender.defense:
            return self.attacker
        elif self.defender.attack > self.attacker.defense:
            return self.defender
        else:
            return "Draw"


0 commentaires