Évitez les boucles imbriquées en PHP et Python

Évitez la notation en boucle imbriquée en utilisant des générateurs en PHP et Python

Lors du décodage et de l'utilisation du JSON suivant, le traitement en boucle peut être décrit par imbrication (imbrication).

nest.json


{
  "a": {"A": {"A0": [1, 2], "A1": [3, 4]}, "B": {"A0": [5, 6], "A1": [7, 8]}},
  "b": {"A": {"A0": [10, 20], "A1": [30, 40]}, "B": {"A0": [50, 60], "A1": [70, 80]}}
}

A ce moment, l'extraction de la valeur de l'index «1» de la clé «A0» a le résultat suivant, mais lors de la réalisation du traitement avec PHP ou Python, il y a des cas où cela devient une double boucle ou une triple boucle.

[2, 6, 20, 60]

Puisqu'un générateur utilisant yield from est disponible en PHP7 et Python3.3 ou version ultérieure, utilisez cette fonction pour vérifier si vous pouvez sortir de la boucle imbriquée. Pour la vérification, PHP 7.1.5 et Python 3.5.0 sont utilisés.

Lorsqu'il est réalisé par une boucle imbriquée

Le code PHP et Python est décrit à titre d'exemple lorsqu'il est réalisé par triple boucle et double boucle.

Pour PHP7

ʻEn supposant que array_walketc. n'est pas utilisé, seulforeach` est utilisé.

<?php

$nest = json_decode(file_get_contents("nest.json"), true);

/*
$nest = [
  "a" => ["A" => ["A0" => [1,2], "A1" => [3,4]], "B" => ["A0" => [5,6], "A1" => [7,8]]],
  "b" => ["A" => ["A0" => [10,20], "A1" => [30,40]], "B" => ["A0" => [50,60], "A1" => [70,80]]]
];
*/

$r = [];
foreach ($nest as $v1) {
    foreach ($v1 as $v2) {
        foreach ($v2 as $k => $v3)  {
            if ($k === "A0") {
                $r[] = $v3[1];
            }
        }
    }
}
print_r($r);

$r = [];
foreach ($nest as $v1) {
    foreach ($v1 as $v2) {
        if (isset($v2["A0"][1]))  {
            $r[] = $v2["A0"][1];
        }
    }
}
print_r($r);

Pour Python 3

Écriture presque identique à PHP.

import json
from collections import OrderedDict

nest = json.load(open("nest.json"), object_pairs_hook=OrderedDict)

"""
nest = {
  "a": {"A": {"A0": [1,2], "A1": [3,4]}, "B": {"A0": [5,6], "A1": [7,8]}},
  "b": {"A": {"A0": [10,20], "A1": [30,40]}, "B": {"A0": [50,60], "A1": [70,80]}}
}
"""

r = []
for v1 in nest.values():
    for v2 in v1.values():
        for k, v3 in v2.items():
            if k == "A0" and len(v3) > 1:
                r.append(v3[1])
print(r)

r = []
for v1 in nest.values():
    for v2 in v1.values():
        if "A0" in v2 and len(v2["A0"]) > 1:
            r.append(v2["A0"][1])
print(r)

Lorsqu'il est réalisé par «rendement de»

PHP et Python peuvent être écrits de la même manière.

Pour PHP7

Ce sera relativement simple. Il n'est pas nécessaire d'ajouter un traitement en boucle même si la hiérarchie du tableau devient plus profonde.

<?php

$nest = json_decode(file_get_contents("nest.json"), true);

function zslice ($n)
{
     foreach($n as $k => $v) {
         yield from $v;
     }
}

$r = [];
foreach(zslice(zslice($nest)) as $k => $v) {
    if ($k == "A0") {
        $r[] = $v[1];
    }
}
print_r($r);

$r = [];
foreach(zslice($nest) as $k => $v) {
    if (isset($v["A0"][1])) {
        $r[] = $v["A0"][1];
    }
}
print_r($r);

Pour Python 3

Puisqu'il est géré par dict, un traitement un peu compliqué est nécessaire, mais la méthode de base est la même que PHP7.

import json
from collections import OrderedDict

nest = json.load(open("nest.json"), object_pairs_hook=OrderedDict)


def zslice(n):
    r = n.values() if isinstance(n, dict) else n
    for v in r:
        if isinstance(v, dict):
            d = v.items()
        elif isinstance(v, tuple) and len(v) > 1:
            d = v[1].items()
        else:
            raise ValueError
        yield from d

r = []
for k, v in zslice(zslice(nest)):
    if k == "A0" and len(v) > 1:
        r.append(v[1])
print(r)

r = []
for k, v in zslice(nest):
    if "A0" in v and len(v["A0"]) > 1:
       r.append(v["A0"][1])
print(r)

Autre

Il peut être plus simple et plus facile à lire en séparant le «zslice» comme indiqué ci-dessous.

import json
from collections import OrderedDict

nest = json.load(open("nest.json"), object_pairs_hook=OrderedDict)


def zslice1(n):
    for v in n.values():
        yield from v.items()


def zslice2(n):
    for k, v in n:
        yield from v.items()

r = []
for k, v in zslice2(zslice1(nest)):
    if k == "A0" and len(v) > 1:
        r.append(v[1])
print(r)

r = []
for k, v in zslice1(nest):
    if "A0" in v and len(v["A0"]) > 1:
       r.append(v["A0"][1])
print(r)

Résultat de sortie

Le résultat de sortie de l'exemple de code PHP et Python décrit ici est décrit.

Pour PHP

python


Array
(
    [0] => 2
    [1] => 6
    [2] => 20
    [3] => 60
)
Array
(
    [0] => 2
    [1] => 6
    [2] => 20
    [3] => 60
)

Pour Python

Résultat de sortie


[2, 6, 20, 60]
[2, 6, 20, 60]

Supplément: À propos de l'ordre des dictionnaires Python

Si ʻobject_pairs_hook = OrderedDict n'est pas spécifié dans le deuxième argument de json.load`, l'ordre des éléments peut être différent si l'échantillon est exécuté plusieurs fois.

modèle 1


[60, 20, 6, 2]
[60, 20, 6, 2]

Motif 2


[6, 2, 60, 20]
[6, 2, 60, 20]

Puisque l'ordre des éléments n'est pas garanti lors de la création de dict, utilisez ʻOrderedDict` pour maintenir la cohérence.

Recommended Posts

Évitez les boucles imbriquées en PHP et Python
Évitez les boucles multiples en Python
POST JSON avec Python et recevez avec PHP
Pile et file d'attente en Python
Évitez KeyError dans le dictionnaire python
Unittest et CI en Python
Un moyen simple d'éviter plusieurs boucles for en Python
Paquets qui gèrent le MIDI avec Python midi et pretty_midi
Différence entre list () et [] en Python
Différence entre == et est en python
Afficher les photos en Python et html
Algorithme de tri et implémentation en Python
Manipuler des fichiers et des dossiers en Python
À propos de Python et Cython dtype
Affectations et modifications des objets Python
Vérifiez et déplacez le répertoire en Python
Chiffrement avec Python: IND-CCA2 et RSA-OAEP
Hashing de données en R et Python
Synthèse de fonctions et application en Python
Exporter et exporter des fichiers en Python
Comparez les boucles de tableau Python et JavaScript
Inverser le pseudonyme plat et le katakana en Python2.7
Lire et écrire du texte en Python
[GUI en Python] Menu PyQt5 et barre d'outils-
Créer et lire des paquets de messages en Python
Chevauchement d'expressions régulières en Python et Java
Différence d'authenticité entre Python et JavaScript
Notes utilisant cChardet et python3-chardet dans Python 3.3.1.
Différences entre Ruby et Python dans la portée
Modulation et démodulation AM avec Python Partie 2
différence entre les instructions (instructions) et les expressions (expressions) en Python
Valeurs authentiques et vecteurs propres: Algèbre linéaire en Python <7>
Module d'implémentation de file d'attente et Python "deque"
Graphique à lignes pliées et ligne d'échelle en python
Obtention d'informations d'identification AWS temporaires en PHP, Python
Implémenter le filtre FIR en langage Python et C
Différences entre la syntaxe Python et Java
Vérifier et recevoir le port série en Python (vérification du port)
Différences dans la relation entre PHP et Python enfin et quitter
Rechercher et lire des vidéos YouTube avec Python
Différence entre @classmethod et @staticmethod en Python
Decorator pour éviter UnicodeEncodeError dans Python 3 print ()
Différence entre append et + = dans la liste Python
Différence entre non local et global en Python
Ecrire le fichier O_SYNC en C et Python
Gérer les "années et mois" en Python
Lire et écrire des fichiers JSON avec Python
Représentez facilement des données graphiques dans le shell et Python
Méthodes et champs privés en python [chiffrement]
Rechercher et vérifier la matrice inverse en Python
Indépendance et base linéaires: Algèbre linéaire en Python <6>
Appelez sudo en Python et mot de passe à saisie automatique
Différences de multithreading entre Python et Jython
Importation de modules et gestion des exceptions en python
Comment utiliser is et == en Python
Projet Euler # 1 "Multiple de 3 et 5" en Python
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Organisez les modules et les packages Python dans le désordre